diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java index 256e6fd5f9..35ec105614 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java @@ -312,6 +312,31 @@ public class AvailableSettings { */ public static final String ENTITY_MANAGER_FACTORY_NAME = "hibernate.ejb.entitymanager_factory_name"; + /** + * @deprecated use {@link #JPA_METAMODEL_POPULATION} instead. + */ + @Deprecated + public static final String JPA_METAMODEL_GENERATION = "hibernate.ejb.metamodel.generation"; + + /** + * Setting that controls whether we seek out JPA "static metamodel" classes and populate them. Accepts + * 3 values: + * + */ + public static final String JPA_METAMODEL_POPULATION = "hibernate.ejb.metamodel.population"; + + /** * List of classes names * Internal use only diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java index e5f5cc87d6..5c2b25b0c4 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java @@ -41,6 +41,8 @@ import javax.persistence.metamodel.Metamodel; import javax.persistence.spi.LoadState; import javax.persistence.spi.PersistenceUnitTransactionType; +import org.jboss.logging.Logger; + import org.hibernate.Hibernate; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @@ -51,6 +53,7 @@ import org.hibernate.ejb.util.PersistenceUtilHelper; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.UUIDGenerator; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.mapping.PersistentClass; import org.hibernate.metadata.ClassMetadata; import org.hibernate.service.ServiceRegistry; @@ -65,6 +68,9 @@ import org.hibernate.service.ServiceRegistry; public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { private static final long serialVersionUID = 5423543L; private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator(); + + private static final Logger log = Logger.getLogger( EntityManagerFactoryImpl.class ); + private final transient SessionFactory sessionFactory; private final transient PersistenceUnitTransactionType transactionType; private final transient boolean discardOnClose; @@ -90,15 +96,16 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { this.discardOnClose = discardOnClose; this.sessionInterceptorClass = sessionInterceptorClass; final Iterator classes = cfg.getClassMappings(); - //a safe guard till we are confident that metamodel is well tested - // disabled: dont create metamodel - // ignoreUnsupported: create metamodel, but ignore unsupported/unknown annotations (like @Any) HHH-6589 - final String ejbMetamodelGenerationProperty = cfg.getProperty( "hibernate.ejb.metamodel.generation" ); - if ( !"disabled".equalsIgnoreCase( ejbMetamodelGenerationProperty ) ) { - this.metamodel = MetamodelImpl.buildMetamodel( classes, ( SessionFactoryImplementor ) sessionFactory, "ignoreUnsupported".equalsIgnoreCase( ejbMetamodelGenerationProperty )); + final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting( cfg ); + if ( JpaMetaModelPopulationSetting.DISABLED == jpaMetaModelPopulationSetting ) { + this.metamodel = null; } else { - this.metamodel = null; + this.metamodel = MetamodelImpl.buildMetamodel( + classes, + ( SessionFactoryImplementor ) sessionFactory, + JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED == jpaMetaModelPopulationSetting + ); } this.criteriaBuilder = new CriteriaBuilderImpl( this ); this.util = new HibernatePersistenceUnitUtil( this ); @@ -117,6 +124,43 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { this.entityManagerFactoryName = entityManagerFactoryName; EntityManagerFactoryRegistry.INSTANCE.addEntityManagerFactory(entityManagerFactoryName, this); } + + private enum JpaMetaModelPopulationSetting { + ENABLED, + DISABLED, + IGNORE_UNSUPPORTED; + + private static JpaMetaModelPopulationSetting parse(String setting) { + if ( "enabled".equalsIgnoreCase( setting ) ) { + return ENABLED; + } + else if ( "disabled".equalsIgnoreCase( setting ) ) { + return DISABLED; + } + else { + return IGNORE_UNSUPPORTED; + } + } + } + + protected JpaMetaModelPopulationSetting determineJpaMetaModelPopulationSetting(Configuration cfg) { + String setting = ConfigurationHelper.getString( + AvailableSettings.JPA_METAMODEL_POPULATION, + cfg.getProperties(), + null + ); + if ( setting == null ) { + setting = ConfigurationHelper.getString( AvailableSettings.JPA_METAMODEL_GENERATION, cfg.getProperties(), null ); + if ( setting != null ) { + log.infof( + "Encountered deprecated setting [%s], use [%s] instead", + AvailableSettings.JPA_METAMODEL_GENERATION, + AvailableSettings.JPA_METAMODEL_POPULATION + ); + } + } + return JpaMetaModelPopulationSetting.parse( setting ); + } private static void addAll(HashMap propertyMap, Properties properties) { for ( Map.Entry entry : properties.entrySet() ) { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java index 330cd1628e..376942d4d4 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java @@ -83,20 +83,36 @@ public class AttributeFactory { public AttributeImplementor buildAttribute(AbstractManagedType ownerType, Property property) { if ( property.isSynthetic() ) { // hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel. - LOG.trace("Skipping synthetic property " + ownerType.getJavaType().getName() + "(" + property.getName() + ")"); + LOG.tracef( + "Skipping synthetic property %s(%s)", + ownerType.getJavaType().getName(), + property.getName() + ); return null; } LOG.trace("Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]"); final AttributeContext attributeContext = wrap( ownerType, property ); final AttributeMetadata attributeMetadata = determineAttributeMetadata( attributeContext, NORMAL_MEMBER_RESOLVER ); - if (attributeMetadata == null) return null; - if (attributeMetadata.isPlural()) return buildPluralAttribute((PluralAttributeMetadata)attributeMetadata); + if (attributeMetadata == null) { + return null; + } + if (attributeMetadata.isPlural()) { + return buildPluralAttribute((PluralAttributeMetadata)attributeMetadata); + } final SingularAttributeMetadata singularAttributeMetadata = (SingularAttributeMetadata)attributeMetadata; final Type metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext()); - return new SingularAttributeImpl(attributeMetadata.getName(), attributeMetadata.getJavaType(), ownerType, - attributeMetadata.getMember(), false, false, property.isOptional(), metaModelType, - attributeMetadata.getPersistentAttributeType()); + return new SingularAttributeImpl( + attributeMetadata.getName(), + attributeMetadata.getJavaType(), + ownerType, + attributeMetadata.getMember(), + false, + false, + property.isOptional(), + metaModelType, + attributeMetadata.getPersistentAttributeType() + ); } private AttributeContext wrap(final AbstractManagedType ownerType, final Property property) { @@ -428,11 +444,12 @@ public class AttributeFactory { LOG.trace(" Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]"); if ( type.isAnyType() ) { + // ANY mappings are currently not supported in the JPA metamodel; see HHH-6589 if ( context.isIgnoreUnsupported() ) { - // HHH-6589 Support "Any" mappings when building metamodel return null; - } else { - throw new UnsupportedOperationException( "any not supported yet" ); + } + else { + throw new UnsupportedOperationException( "ANY not supported" ); } } else if ( type.isAssociationType() ) { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java index 1c4b13a9f1..45ed872657 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java @@ -48,9 +48,12 @@ public class MetamodelImpl implements Metamodel, Serializable { * {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}. * * @param persistentClasses Iterator over the Hibernate (config-time) metamodel - * @param sessionFactory The Hibernate session factry. + * @param sessionFactory The Hibernate session factory. * @return The built metamodel + * + * @deprecated use {@link #buildMetamodel(java.util.Iterator,org.hibernate.engine.spi.SessionFactoryImplementor,boolean)} instead */ + @Deprecated public static MetamodelImpl buildMetamodel( Iterator persistentClasses, SessionFactoryImplementor sessionFactory) { @@ -62,7 +65,7 @@ public class MetamodelImpl implements Metamodel, Serializable { * {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}. * * @param persistentClasses Iterator over the Hibernate (config-time) metamodel - * @param sessionFactory The Hibernate session factry. + * @param sessionFactory The Hibernate session factory. * @param ignoreUnsupported ignore unsupported/unknown annotations (like @Any) * @return The built metamodel */ diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java index 7047fc557a..e78e465961 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java @@ -73,7 +73,7 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase { cfg.addAnnotatedClass( WithGenericCollection.class ); cfg.buildMappings(); SessionFactoryImplementor sfi = (SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry() ); - MetamodelImpl.buildMetamodel( cfg.getClassMappings(), sfi ); + MetamodelImpl.buildMetamodel( cfg.getClassMappings(), sfi, true ); } @Test