HHH-6589 - Skip non-JPA features populating JPA "static metamodel"
This commit is contained in:
parent
f4c9b284a1
commit
f26435dfec
|
@ -312,6 +312,31 @@ public class AvailableSettings {
|
||||||
*/
|
*/
|
||||||
public static final String ENTITY_MANAGER_FACTORY_NAME = "hibernate.ejb.entitymanager_factory_name";
|
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:<ul>
|
||||||
|
* <li>
|
||||||
|
* <b>enabled</b> - Do the population
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* <b>disabled</b> - Do not do the population
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* <b>ignoreUnsupported</b> - Do the population, but ignore any non-JPA features that would otherwise
|
||||||
|
* result in the population failing.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static final String JPA_METAMODEL_POPULATION = "hibernate.ejb.metamodel.population";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of classes names
|
* List of classes names
|
||||||
* Internal use only
|
* Internal use only
|
||||||
|
|
|
@ -41,6 +41,8 @@ import javax.persistence.metamodel.Metamodel;
|
||||||
import javax.persistence.spi.LoadState;
|
import javax.persistence.spi.LoadState;
|
||||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
|
@ -51,6 +53,7 @@ import org.hibernate.ejb.util.PersistenceUtilHelper;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.id.UUIDGenerator;
|
import org.hibernate.id.UUIDGenerator;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.metadata.ClassMetadata;
|
import org.hibernate.metadata.ClassMetadata;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -65,6 +68,9 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
||||||
private static final long serialVersionUID = 5423543L;
|
private static final long serialVersionUID = 5423543L;
|
||||||
private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator();
|
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 SessionFactory sessionFactory;
|
||||||
private final transient PersistenceUnitTransactionType transactionType;
|
private final transient PersistenceUnitTransactionType transactionType;
|
||||||
private final transient boolean discardOnClose;
|
private final transient boolean discardOnClose;
|
||||||
|
@ -90,15 +96,16 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
||||||
this.discardOnClose = discardOnClose;
|
this.discardOnClose = discardOnClose;
|
||||||
this.sessionInterceptorClass = sessionInterceptorClass;
|
this.sessionInterceptorClass = sessionInterceptorClass;
|
||||||
final Iterator<PersistentClass> classes = cfg.getClassMappings();
|
final Iterator<PersistentClass> classes = cfg.getClassMappings();
|
||||||
//a safe guard till we are confident that metamodel is well tested
|
final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting( cfg );
|
||||||
// disabled: dont create metamodel
|
if ( JpaMetaModelPopulationSetting.DISABLED == jpaMetaModelPopulationSetting ) {
|
||||||
// ignoreUnsupported: create metamodel, but ignore unsupported/unknown annotations (like @Any) HHH-6589
|
this.metamodel = null;
|
||||||
final String ejbMetamodelGenerationProperty = cfg.getProperty( "hibernate.ejb.metamodel.generation" );
|
|
||||||
if ( !"disabled".equalsIgnoreCase( ejbMetamodelGenerationProperty ) ) {
|
|
||||||
this.metamodel = MetamodelImpl.buildMetamodel( classes, ( SessionFactoryImplementor ) sessionFactory, "ignoreUnsupported".equalsIgnoreCase( ejbMetamodelGenerationProperty ));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.metamodel = null;
|
this.metamodel = MetamodelImpl.buildMetamodel(
|
||||||
|
classes,
|
||||||
|
( SessionFactoryImplementor ) sessionFactory,
|
||||||
|
JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED == jpaMetaModelPopulationSetting
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.criteriaBuilder = new CriteriaBuilderImpl( this );
|
this.criteriaBuilder = new CriteriaBuilderImpl( this );
|
||||||
this.util = new HibernatePersistenceUnitUtil( this );
|
this.util = new HibernatePersistenceUnitUtil( this );
|
||||||
|
@ -117,6 +124,43 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
||||||
this.entityManagerFactoryName = entityManagerFactoryName;
|
this.entityManagerFactoryName = entityManagerFactoryName;
|
||||||
EntityManagerFactoryRegistry.INSTANCE.addEntityManagerFactory(entityManagerFactoryName, this);
|
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<String, Object> propertyMap, Properties properties) {
|
private static void addAll(HashMap<String, Object> propertyMap, Properties properties) {
|
||||||
for ( Map.Entry entry : properties.entrySet() ) {
|
for ( Map.Entry entry : properties.entrySet() ) {
|
||||||
|
|
|
@ -83,20 +83,36 @@ public class AttributeFactory {
|
||||||
public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property) {
|
public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property) {
|
||||||
if ( property.isSynthetic() ) {
|
if ( property.isSynthetic() ) {
|
||||||
// hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel.
|
// 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;
|
return null;
|
||||||
}
|
}
|
||||||
LOG.trace("Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]");
|
LOG.trace("Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]");
|
||||||
final AttributeContext<X> attributeContext = wrap( ownerType, property );
|
final AttributeContext<X> attributeContext = wrap( ownerType, property );
|
||||||
final AttributeMetadata<X,Y> attributeMetadata =
|
final AttributeMetadata<X,Y> attributeMetadata =
|
||||||
determineAttributeMetadata( attributeContext, NORMAL_MEMBER_RESOLVER );
|
determineAttributeMetadata( attributeContext, NORMAL_MEMBER_RESOLVER );
|
||||||
if (attributeMetadata == null) return null;
|
if (attributeMetadata == null) {
|
||||||
if (attributeMetadata.isPlural()) return buildPluralAttribute((PluralAttributeMetadata)attributeMetadata);
|
return null;
|
||||||
|
}
|
||||||
|
if (attributeMetadata.isPlural()) {
|
||||||
|
return buildPluralAttribute((PluralAttributeMetadata)attributeMetadata);
|
||||||
|
}
|
||||||
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>)attributeMetadata;
|
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>)attributeMetadata;
|
||||||
final Type<Y> metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext());
|
final Type<Y> metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext());
|
||||||
return new SingularAttributeImpl<X, Y>(attributeMetadata.getName(), attributeMetadata.getJavaType(), ownerType,
|
return new SingularAttributeImpl<X, Y>(
|
||||||
attributeMetadata.getMember(), false, false, property.isOptional(), metaModelType,
|
attributeMetadata.getName(),
|
||||||
attributeMetadata.getPersistentAttributeType());
|
attributeMetadata.getJavaType(),
|
||||||
|
ownerType,
|
||||||
|
attributeMetadata.getMember(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
property.isOptional(),
|
||||||
|
metaModelType,
|
||||||
|
attributeMetadata.getPersistentAttributeType()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> AttributeContext<X> wrap(final AbstractManagedType<X> ownerType, final Property property) {
|
private <X> AttributeContext<X> wrap(final AbstractManagedType<X> ownerType, final Property property) {
|
||||||
|
@ -428,11 +444,12 @@ public class AttributeFactory {
|
||||||
LOG.trace(" Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]");
|
LOG.trace(" Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]");
|
||||||
|
|
||||||
if ( type.isAnyType() ) {
|
if ( type.isAnyType() ) {
|
||||||
|
// ANY mappings are currently not supported in the JPA metamodel; see HHH-6589
|
||||||
if ( context.isIgnoreUnsupported() ) {
|
if ( context.isIgnoreUnsupported() ) {
|
||||||
// HHH-6589 Support "Any" mappings when building metamodel
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
}
|
||||||
throw new UnsupportedOperationException( "any not supported yet" );
|
else {
|
||||||
|
throw new UnsupportedOperationException( "ANY not supported" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( type.isAssociationType() ) {
|
else if ( type.isAssociationType() ) {
|
||||||
|
|
|
@ -48,9 +48,12 @@ public class MetamodelImpl implements Metamodel, Serializable {
|
||||||
* {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}.
|
* {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}.
|
||||||
*
|
*
|
||||||
* @param persistentClasses Iterator over the Hibernate (config-time) metamodel
|
* @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
|
* @return The built metamodel
|
||||||
|
*
|
||||||
|
* @deprecated use {@link #buildMetamodel(java.util.Iterator,org.hibernate.engine.spi.SessionFactoryImplementor,boolean)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static MetamodelImpl buildMetamodel(
|
public static MetamodelImpl buildMetamodel(
|
||||||
Iterator<PersistentClass> persistentClasses,
|
Iterator<PersistentClass> persistentClasses,
|
||||||
SessionFactoryImplementor sessionFactory) {
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
@ -62,7 +65,7 @@ public class MetamodelImpl implements Metamodel, Serializable {
|
||||||
* {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}.
|
* {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}.
|
||||||
*
|
*
|
||||||
* @param persistentClasses Iterator over the Hibernate (config-time) metamodel
|
* @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)
|
* @param ignoreUnsupported ignore unsupported/unknown annotations (like @Any)
|
||||||
* @return The built metamodel
|
* @return The built metamodel
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
cfg.addAnnotatedClass( WithGenericCollection.class );
|
cfg.addAnnotatedClass( WithGenericCollection.class );
|
||||||
cfg.buildMappings();
|
cfg.buildMappings();
|
||||||
SessionFactoryImplementor sfi = (SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry() );
|
SessionFactoryImplementor sfi = (SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry() );
|
||||||
MetamodelImpl.buildMetamodel( cfg.getClassMappings(), sfi );
|
MetamodelImpl.buildMetamodel( cfg.getClassMappings(), sfi, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue