Allow for customizing the Hibernate MetadataSources instance

Issue: SPR-13710
master
Juergen Hoeller 9 years ago
parent f8860e2938
commit dd930b3b66
  1. 52
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java
  2. 17
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java

@ -23,8 +23,10 @@ import javax.sql.DataSource;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
@ -40,6 +42,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
/**
* {@link FactoryBean} that creates a Hibernate
@ -96,7 +99,9 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
private AsyncTaskExecutor bootstrapExecutor;
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private MetadataSources metadataSources;
private ResourcePatternResolver resourcePatternResolver;
private Configuration configuration;
@ -318,15 +323,58 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
this.bootstrapExecutor = bootstrapExecutor;
}
/**
* Specify a Hibernate {@link MetadataSources} service to use (e.g. reusing an
* existing one), potentially populated with a custom Hibernate bootstrap
* {@link org.hibernate.service.ServiceRegistry} as well.
* @since 4.3
*/
public void setMetadataSources(MetadataSources metadataSources) {
Assert.notNull(metadataSources, "MetadataSources must not be null");
this.metadataSources = metadataSources;
}
/**
* Determine the Hibernate {@link MetadataSources} to use.
* <p>Can also be externally called to initialize and pre-populate a {@link MetadataSources}
* instance which is then going to be used for {@link SessionFactory} building.
* @return the MetadataSources to use (never {@code null})
* @since 4.3
* @see LocalSessionFactoryBuilder#LocalSessionFactoryBuilder(DataSource, ResourceLoader, MetadataSources)
*/
public MetadataSources getMetadataSources() {
if (this.metadataSources == null) {
this.metadataSources = new MetadataSources(new BootstrapServiceRegistryBuilder().build());
}
return this.metadataSources;
}
/**
* Specify a Spring {@link ResourceLoader} to use for Hibernate metadata.
* @param resourceLoader the ResourceLoader to use (never {@code null})
*/
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
}
/**
* Determine the Spring {@link ResourceLoader} to use for Hibernate metadata.
* @return the ResourceLoader to use (never {@code null})
* @since 4.3
*/
public ResourceLoader getResourceLoader() {
if (this.resourcePatternResolver == null) {
this.resourcePatternResolver = new PathMatchingResourcePatternResolver();
}
return this.resourcePatternResolver;
}
@Override
public void afterPropertiesSet() throws IOException {
LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver);
LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(
this.dataSource, getResourceLoader(), getMetadataSources());
if (this.configLocations != null) {
for (Resource resource : this.configLocations) {

@ -38,6 +38,8 @@ import javax.transaction.TransactionManager;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
@ -116,6 +118,20 @@ public class LocalSessionFactoryBuilder extends Configuration {
* @param resourceLoader the ResourceLoader to load application classes from
*/
public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader) {
this(dataSource, resourceLoader, new MetadataSources(new BootstrapServiceRegistryBuilder().build()));
}
/**
* Create a new LocalSessionFactoryBuilder for the given DataSource.
* @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using
* (may be {@code null})
* @param resourceLoader the ResourceLoader to load application classes from
* @param metadataSources the Hibernate MetadataSources service to use (e.g. reusing an existing one)
* @since 4.3
*/
public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader, MetadataSources metadataSources) {
super(metadataSources);
getProperties().put(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
if (dataSource != null) {
getProperties().put(Environment.DATASOURCE, dataSource);
@ -298,6 +314,7 @@ public class LocalSessionFactoryBuilder extends Configuration {
/**
* Proxy invocation handler for background bootstrapping, only enforcing
* a fully initialized target {@code SessionFactory} when actually needed.
* @since 4.3
*/
private class BootstrapSessionFactoryInvocationHandler implements InvocationHandler {

Loading…
Cancel
Save