From 3227569a38a677aeebee6cb13d945c3fea6c10cb Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 7 Aug 2014 22:20:40 +0200 Subject: [PATCH] LocalSessionFactoryBean/Builder allows for specifying custom entity type filters Issue: SPR-12049 --- .../hibernate4/LocalSessionFactoryBean.java | 22 +++++++++++ .../LocalSessionFactoryBuilder.java | 38 ++++++++++++++----- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java index e9f7318c14..25cc4295fa 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java @@ -37,6 +37,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternUtils; +import org.springframework.core.type.filter.TypeFilter; /** * {@link org.springframework.beans.factory.FactoryBean} that creates a Hibernate @@ -95,6 +96,8 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator private RegionFactory cacheRegionFactory; + private TypeFilter[] entityTypeFilters; + private Properties hibernateProperties; private Class[] annotatedClasses; @@ -238,6 +241,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator * on to the SessionFactory: as an instance, a Class, or a String class name. *

Note that the package location of the {@code MultiTenantConnectionProvider} * interface changed between Hibernate 4.2 and 4.3. This method accepts both variants. + * @since 4.0 * @see LocalSessionFactoryBuilder#setMultiTenantConnectionProvider */ public void setMultiTenantConnectionProvider(Object multiTenantConnectionProvider) { @@ -247,6 +251,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator /** * Set a Hibernate 4.1/4.2/4.3 {@code CurrentTenantIdentifierResolver} to be passed * on to the SessionFactory: as an instance, a Class, or a String class name. + * @since 4.0 * @see LocalSessionFactoryBuilder#setCurrentTenantIdentifierResolver */ public void setCurrentTenantIdentifierResolver(Object currentTenantIdentifierResolver) { @@ -258,6 +263,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator * Allows for using a Spring-managed RegionFactory instance. *

Note: If this is set, the Hibernate settings should not define a * cache provider to avoid meaningless double configuration. + * @since 4.0 * @see org.hibernate.cache.spi.RegionFactory * @see LocalSessionFactoryBuilder#setCacheRegionFactory */ @@ -265,6 +271,18 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator this.cacheRegionFactory = cacheRegionFactory; } + /** + * Specify custom type filters for Spring-based scanning for entity classes. + *

Default is to search all specified packages for classes annotated with + * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} + * or {@code @javax.persistence.MappedSuperclass}. + * @since 4.1 + * @see #setPackagesToScan + */ + public void setEntityTypeFilters(TypeFilter... entityTypeFilters) { + this.entityTypeFilters = entityTypeFilters; + } + /** * Set Hibernate properties, such as "hibernate.dialect". *

Note: Do not specify a transaction provider here when using @@ -395,6 +413,10 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator sfb.setCacheRegionFactory(this.cacheRegionFactory); } + if (this.entityTypeFilters != null) { + sfb.setEntityTypeFilters(this.entityTypeFilters); + } + if (this.hibernateProperties != null) { sfb.addProperties(this.hibernateProperties); } diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java index 659afaf09b..60cc8cccec 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java @@ -84,18 +84,18 @@ public class LocalSessionFactoryBuilder extends Configuration { private static final String PACKAGE_INFO_SUFFIX = ".package-info"; - private static final Set entityTypeFilters; + private static final Set defaultTypeFilters; static { - entityTypeFilters = new LinkedHashSet(4); - entityTypeFilters.add(new AnnotationTypeFilter(Entity.class, false)); - entityTypeFilters.add(new AnnotationTypeFilter(Embeddable.class, false)); - entityTypeFilters.add(new AnnotationTypeFilter(MappedSuperclass.class, false)); + defaultTypeFilters = new LinkedHashSet(4); + defaultTypeFilters.add(new AnnotationTypeFilter(Entity.class, false)); + defaultTypeFilters.add(new AnnotationTypeFilter(Embeddable.class, false)); + defaultTypeFilters.add(new AnnotationTypeFilter(MappedSuperclass.class, false)); try { @SuppressWarnings("unchecked") Class converterAnnotation = (Class) ClassUtils.forName("javax.persistence.Converter", LocalSessionFactoryBuilder.class.getClassLoader()); - entityTypeFilters.add(new AnnotationTypeFilter(converterAnnotation, false)); + defaultTypeFilters.add(new AnnotationTypeFilter(converterAnnotation, false)); } catch (ClassNotFoundException ex) { // JPA 2.1 API not available - Hibernate <4.3 @@ -103,6 +103,8 @@ public class LocalSessionFactoryBuilder extends Configuration { } + private TypeFilter[] entityTypeFilters = defaultTypeFilters.toArray(new TypeFilter[defaultTypeFilters.size()]); + private final ResourcePatternResolver resourcePatternResolver; private RegionFactory cacheRegionFactory; @@ -194,6 +196,7 @@ public class LocalSessionFactoryBuilder extends Configuration { * on to the SessionFactory: as an instance, a Class, or a String class name. *

Note that the package location of the {@code MultiTenantConnectionProvider} * interface changed between Hibernate 4.2 and 4.3. This method accepts both variants. + * @since 4.0 * @see AvailableSettings#MULTI_TENANT_CONNECTION_PROVIDER */ public LocalSessionFactoryBuilder setMultiTenantConnectionProvider(Object multiTenantConnectionProvider) { @@ -204,6 +207,7 @@ public class LocalSessionFactoryBuilder extends Configuration { /** * Set a Hibernate 4.1/4.2/4.3 {@code CurrentTenantIdentifierResolver} to be passed * on to the SessionFactory: as an instance, a Class, or a String class name. + * @since 4.0 * @see AvailableSettings#MULTI_TENANT_IDENTIFIER_RESOLVER */ public LocalSessionFactoryBuilder setCurrentTenantIdentifierResolver(Object currentTenantIdentifierResolver) { @@ -216,6 +220,7 @@ public class LocalSessionFactoryBuilder extends Configuration { * Allows for using a Spring-managed RegionFactory instance. *

Note: If this is set, the Hibernate settings should not define a * cache provider to avoid meaningless double configuration. + * @since 4.0 * @see org.hibernate.cache.spi.RegionFactory */ public LocalSessionFactoryBuilder setCacheRegionFactory(RegionFactory cacheRegionFactory) { @@ -223,6 +228,19 @@ public class LocalSessionFactoryBuilder extends Configuration { return this; } + /** + * Specify custom type filters for Spring-based scanning for entity classes. + *

Default is to search all specified packages for classes annotated with + * {@code @javax.persistence.Entity}, {@code @javax.persistence.Embeddable} + * or {@code @javax.persistence.MappedSuperclass}. + * @since 4.1 + * @see #scanPackages + */ + public LocalSessionFactoryBuilder setEntityTypeFilters(TypeFilter... entityTypeFilters) { + this.entityTypeFilters = entityTypeFilters; + return this; + } + /** * Add the given annotated classes in a batch. * @see #addAnnotatedClass @@ -298,9 +316,11 @@ public class LocalSessionFactoryBuilder extends Configuration { * the current class descriptor contained in the metadata reader. */ private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException { - for (TypeFilter filter : entityTypeFilters) { - if (filter.match(reader, readerFactory)) { - return true; + if (this.entityTypeFilters != null) { + for (TypeFilter filter : this.entityTypeFilters) { + if (filter.match(reader, readerFactory)) { + return true; + } } } return false; -- GitLab