Skip to content

Commit dd930b3

Browse files
committed
Allow for customizing the Hibernate MetadataSources instance
Issue: SPR-13710
1 parent f8860e2 commit dd930b3

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323

2424
import org.hibernate.Interceptor;
2525
import org.hibernate.SessionFactory;
26+
import org.hibernate.boot.MetadataSources;
2627
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
2728
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
29+
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
2830
import org.hibernate.cfg.Configuration;
2931
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
3032

@@ -40,6 +42,7 @@
4042
import org.springframework.core.io.support.ResourcePatternUtils;
4143
import org.springframework.core.task.AsyncTaskExecutor;
4244
import org.springframework.core.type.filter.TypeFilter;
45+
import org.springframework.util.Assert;
4346

4447
/**
4548
* {@link FactoryBean} that creates a Hibernate
@@ -96,7 +99,9 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
9699

97100
private AsyncTaskExecutor bootstrapExecutor;
98101

99-
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
102+
private MetadataSources metadataSources;
103+
104+
private ResourcePatternResolver resourcePatternResolver;
100105

101106
private Configuration configuration;
102107

@@ -318,15 +323,58 @@ public void setBootstrapExecutor(AsyncTaskExecutor bootstrapExecutor) {
318323
this.bootstrapExecutor = bootstrapExecutor;
319324
}
320325

326+
/**
327+
* Specify a Hibernate {@link MetadataSources} service to use (e.g. reusing an
328+
* existing one), potentially populated with a custom Hibernate bootstrap
329+
* {@link org.hibernate.service.ServiceRegistry} as well.
330+
* @since 4.3
331+
*/
332+
public void setMetadataSources(MetadataSources metadataSources) {
333+
Assert.notNull(metadataSources, "MetadataSources must not be null");
334+
this.metadataSources = metadataSources;
335+
}
336+
337+
/**
338+
* Determine the Hibernate {@link MetadataSources} to use.
339+
* <p>Can also be externally called to initialize and pre-populate a {@link MetadataSources}
340+
* instance which is then going to be used for {@link SessionFactory} building.
341+
* @return the MetadataSources to use (never {@code null})
342+
* @since 4.3
343+
* @see LocalSessionFactoryBuilder#LocalSessionFactoryBuilder(DataSource, ResourceLoader, MetadataSources)
344+
*/
345+
public MetadataSources getMetadataSources() {
346+
if (this.metadataSources == null) {
347+
this.metadataSources = new MetadataSources(new BootstrapServiceRegistryBuilder().build());
348+
}
349+
return this.metadataSources;
350+
}
351+
352+
/**
353+
* Specify a Spring {@link ResourceLoader} to use for Hibernate metadata.
354+
* @param resourceLoader the ResourceLoader to use (never {@code null})
355+
*/
321356
@Override
322357
public void setResourceLoader(ResourceLoader resourceLoader) {
323358
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
324359
}
325360

361+
/**
362+
* Determine the Spring {@link ResourceLoader} to use for Hibernate metadata.
363+
* @return the ResourceLoader to use (never {@code null})
364+
* @since 4.3
365+
*/
366+
public ResourceLoader getResourceLoader() {
367+
if (this.resourcePatternResolver == null) {
368+
this.resourcePatternResolver = new PathMatchingResourcePatternResolver();
369+
}
370+
return this.resourcePatternResolver;
371+
}
372+
326373

327374
@Override
328375
public void afterPropertiesSet() throws IOException {
329-
LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver);
376+
LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(
377+
this.dataSource, getResourceLoader(), getMetadataSources());
330378

331379
if (this.configLocations != null) {
332380
for (Resource resource : this.configLocations) {

spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import org.hibernate.HibernateException;
3939
import org.hibernate.MappingException;
4040
import org.hibernate.SessionFactory;
41+
import org.hibernate.boot.MetadataSources;
42+
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
4143
import org.hibernate.cfg.AvailableSettings;
4244
import org.hibernate.cfg.Configuration;
4345
import org.hibernate.cfg.Environment;
@@ -116,6 +118,20 @@ public LocalSessionFactoryBuilder(DataSource dataSource, ClassLoader classLoader
116118
* @param resourceLoader the ResourceLoader to load application classes from
117119
*/
118120
public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader) {
121+
this(dataSource, resourceLoader, new MetadataSources(new BootstrapServiceRegistryBuilder().build()));
122+
}
123+
124+
/**
125+
* Create a new LocalSessionFactoryBuilder for the given DataSource.
126+
* @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using
127+
* (may be {@code null})
128+
* @param resourceLoader the ResourceLoader to load application classes from
129+
* @param metadataSources the Hibernate MetadataSources service to use (e.g. reusing an existing one)
130+
* @since 4.3
131+
*/
132+
public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader, MetadataSources metadataSources) {
133+
super(metadataSources);
134+
119135
getProperties().put(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
120136
if (dataSource != null) {
121137
getProperties().put(Environment.DATASOURCE, dataSource);
@@ -298,6 +314,7 @@ public SessionFactory buildSessionFactory(AsyncTaskExecutor bootstrapExecutor) {
298314
/**
299315
* Proxy invocation handler for background bootstrapping, only enforcing
300316
* a fully initialized target {@code SessionFactory} when actually needed.
317+
* @since 4.3
301318
*/
302319
private class BootstrapSessionFactoryInvocationHandler implements InvocationHandler {
303320

0 commit comments

Comments
 (0)