Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hibernate 5 LocalSessionFactoryBean should allow for dynamic mapping registration (like for Hibernate 4) [SPR-14815] #19381

Closed
spring-projects-issues opened this issue Oct 17, 2016 · 4 comments

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 17, 2016

Arunkumar opened SPR-14815 and commented

We are working on a project where we have to invoke the
localSessionFactoryBean.afterPropertiesSet(); to reload the hibernate's session factory to add dynamically created HBM from our application, but we got the org.hibernate.DuplicateMappingException.

Upon debugging hibernate5.2.2 source code, we found that the issue starts at the localSessionFactoryBean.afterPropertiesSet().

@Override
	public void afterPropertiesSet() throws IOException {
		LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(
				this.dataSource, getResourceLoader(), getMetadataSources());

// Here the getMetadataSources() has been reused in LocalSessionFactoryBuilder

public MetadataSources getMetadataSources() {
		if (this.metadataSources == null) {
			BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
			if (this.resourcePatternResolver != null) {
				builder = builder.applyClassLoader(this.resourcePatternResolver.getClassLoader());
			}
			this.metadataSources = new MetadataSources(builder.build());
		}
		return this.metadataSources;
	}

/*Here the previously created metadatasources values are being returned without clearing the xmlbindings values, so hibernate again adds (duplicates) all the .hbm  files to its sessionfactory which finally results in DuplicateMappingException. */

As a quick fix in our code we have cleared the getMetadataSources.getXnlBindings

localSessionFactoryBean.getMetadataSources().getXmlBindings().clear();
//and then we called the 
localSessionFactoryBean.afterPropertiesSet();

This scenario will be reproduced only when we have the joined subclass hbm mapping, because in hiberanate 5.2.2 the duplication validation happens at InFlightMetadataCollectorImpl (Line No: 268). This method will be invoked by ModelBinder class method : bindJoinedSubclassEntities( Line No: 576).


Affects: 4.3.3

Issue Links:

  • #18285 Hibernate5 metadata access

Referenced from: commits 5912d6f, 7cbab0e

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 17, 2016

Juergen Hoeller commented

It's not clear to me what we could do better here. LocalSessionFactoryBean isn't really designed for registering dynamic mappings to begin with, so this looks like an enhancement request to me. However, what specifically could we be improving to make your case work?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 17, 2016

Arunkumar commented

In Hibernate4.LocalSessionFactoryBean.afterPropertiesSet() , LocalSessionFactoryBuilder constructor has only (this.datasource, this.resourcePatternResolver) in constructor argument whereas in In Hibernate5.LocalSessionFactoryBean.afterPropertiesSet() the LocalSessionFactoryBuilder has metaDataSource along with datasource and resourcePatternResolver as constructor argument. This leads to the duplicate files added in xmlBinding variable in metadatasources and lead to DuplicatMappingException in Hibernate package.

Is there any specific reason to reuse the metadaSources in Hibernate5.LocalSessionFactoryBean ? because in 3 and 4 ORM packagaes it was working fine and we have been using it for long time.

It will be good if you can add the enhancement request for registering the dynamic mapping of .hbm files. Meanwhile we will use localSessionFactoryBean.getMetadataSources().getXmlBindings().clear(); as our workaround.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 27, 2016

Juergen Hoeller commented

As of 4.3.4, we're resetting the MetadataSources in afterPropertiesSet if they haven't been user-accessed (i.e. if there were no interactions with setMetadataSources / getMetadataSources. This should still allow for MetadataSources customizations as per #18285 while also covering your re-initialization case.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 27, 2016

Arunkumar commented

Thank you so much !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants