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";
|
||||
|
||||
/**
|
||||
* @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
|
||||
* Internal use only
|
||||
|
|
|
@ -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<PersistentClass> 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<String, Object> propertyMap, Properties properties) {
|
||||
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) {
|
||||
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<X> attributeContext = wrap( ownerType, property );
|
||||
final AttributeMetadata<X,Y> 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<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>)attributeMetadata;
|
||||
final Type<Y> metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext());
|
||||
return new SingularAttributeImpl<X, Y>(attributeMetadata.getName(), attributeMetadata.getJavaType(), ownerType,
|
||||
attributeMetadata.getMember(), false, false, property.isOptional(), metaModelType,
|
||||
attributeMetadata.getPersistentAttributeType());
|
||||
return new SingularAttributeImpl<X, Y>(
|
||||
attributeMetadata.getName(),
|
||||
attributeMetadata.getJavaType(),
|
||||
ownerType,
|
||||
attributeMetadata.getMember(),
|
||||
false,
|
||||
false,
|
||||
property.isOptional(),
|
||||
metaModelType,
|
||||
attributeMetadata.getPersistentAttributeType()
|
||||
);
|
||||
}
|
||||
|
||||
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() + "]");
|
||||
|
||||
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() ) {
|
||||
|
|
|
@ -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<PersistentClass> 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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue