From f77b068e91106d2f52efb85d9b07a91dd10c9481 Mon Sep 17 00:00:00 2001 From: Brad Koehn Date: Wed, 27 Mar 2013 09:41:19 -0500 Subject: [PATCH] HHH-7714 Add support for EntityMode.MAP to JPA Criteria API (cherry picked from commit 2758b8b49400b3aae6fbbfc78226f1f622f1bae5) Conflicts: hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java --- .../java/org/hibernate/type/EntityType.java | 35 +++++----- .../jpa/criteria/CriteriaQueryImpl.java | 3 +- .../jpa/criteria/predicate/InPredicate.java | 5 +- .../metamodel/AbstractIdentifiableType.java | 3 +- .../metamodel/AbstractManagedType.java | 4 +- .../jpa/internal/metamodel/AbstractType.java | 46 +++++++++++-- .../internal/metamodel/AttributeFactory.java | 64 ++++++++++++------- .../metamodel/EmbeddableTypeImpl.java | 2 +- .../internal/metamodel/EntityTypeImpl.java | 26 +++++--- .../jpa/internal/metamodel/MapMember.java | 39 +++++++++++ .../metamodel/MappedSuperclassTypeImpl.java | 34 ++++++++-- .../internal/metamodel/MetadataContext.java | 22 ++++--- .../jpa/internal/metamodel/MetamodelImpl.java | 46 ++++++------- 13 files changed, 228 insertions(+), 101 deletions(-) mode change 100644 => 100755 hibernate-core/src/main/java/org/hibernate/type/EntityType.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractType.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AttributeFactory.java create mode 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MapMember.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java mode change 100644 => 100755 hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java diff --git a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java old mode 100644 new mode 100755 index 0451e09dcc..4ee8ed7744 --- a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java @@ -23,24 +23,14 @@ */ package org.hibernate.type; -import java.io.Serializable; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Map; - import org.dom4j.Element; import org.dom4j.Node; - import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.engine.internal.ForeignKeys; -import org.hibernate.engine.spi.EntityUniqueKey; -import org.hibernate.engine.spi.Mapping; -import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.*; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; @@ -48,6 +38,11 @@ import org.hibernate.persister.entity.UniqueKeyLoadable; import org.hibernate.proxy.HibernateProxy; import org.hibernate.tuple.ElementWrapper; +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; + /** * Base for types which map associations to persistent entities. * @@ -236,14 +231,16 @@ public abstract class EntityType extends AbstractType implements AssociationType return returnedClass; } - private Class determineAssociatedEntityClass() { - try { - return ReflectHelper.classForName( getAssociatedEntityName() ); - } - catch ( ClassNotFoundException cnfe ) { - return java.util.Map.class; - } - } + private Class determineAssociatedEntityClass() { + final String entityName = getAssociatedEntityName(); + try { + return ReflectHelper.classForName(entityName); + } + catch ( ClassNotFoundException cnfe ) { + return this.scope.resolveFactory().getEntityPersister(entityName). + getEntityTuplizer().getMappedClass(); + } + } /** * {@inheritDoc} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java old mode 100644 new mode 100755 index 1f5e1151f6..b44ae088bc --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java @@ -336,7 +336,8 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< } Root root = getRoots().iterator().next(); - if ( root.getModel().getJavaType() != returnType ) { + Class javaType = root.getModel().getJavaType(); + if ( javaType != null && javaType != returnType ) { return false; } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java old mode 100644 new mode 100755 index 3291575b08..5344c32354 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/predicate/InPredicate.java @@ -119,8 +119,9 @@ public class InPredicate super( criteriaBuilder ); this.expression = expression; this.values = new ArrayList>( values.size() ); - ValueHandlerFactory.ValueHandler valueHandler = ValueHandlerFactory.isNumeric( expression.getJavaType() ) - ? ValueHandlerFactory.determineAppropriateHandler( (Class) expression.getJavaType() ) + final Class javaType = expression.getJavaType(); + ValueHandlerFactory.ValueHandler valueHandler = javaType != null && ValueHandlerFactory.isNumeric(javaType) + ? ValueHandlerFactory.determineAppropriateHandler((Class) javaType) : new ValueHandlerFactory.NoOpValueHandler(); for ( T value : values ) { this.values.add( diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractIdentifiableType.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractIdentifiableType.java index 774a994985..1d9f85deb2 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractIdentifiableType.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractIdentifiableType.java @@ -54,10 +54,11 @@ public abstract class AbstractIdentifiableType public AbstractIdentifiableType( Class javaType, + String typeName, AbstractIdentifiableType superType, boolean hasIdentifierProperty, boolean versioned) { - super( javaType, superType ); + super( javaType, typeName, superType ); this.hasIdentifierProperty = hasIdentifierProperty; isVersioned = versioned; } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractManagedType.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractManagedType.java index b7f846bee7..effc185a7f 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractManagedType.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractManagedType.java @@ -58,8 +58,8 @@ public abstract class AbstractManagedType private final Map> declaredPluralAttributes = new HashMap>(); - protected AbstractManagedType(Class javaType, AbstractManagedType superType) { - super( javaType ); + protected AbstractManagedType(Class javaType, String typeName, AbstractManagedType superType) { + super( javaType, typeName ); this.superType = superType; } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractType.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractType.java old mode 100644 new mode 100755 index 4e391bdf31..84cb83723b --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractType.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AbstractType.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.jpa.internal.metamodel; + import java.io.Serializable; import javax.persistence.metamodel.Type; @@ -29,15 +30,50 @@ import javax.persistence.metamodel.Type; * Defines commonality for the JPA {@link Type} hierarchy of interfaces. * * @author Steve Ebersole + * @author Brad Koehn */ public abstract class AbstractType implements Type, Serializable { - private final Class javaType; + private final Class javaType; + private final String typeName; - public AbstractType(Class javaType) { + /** + * Instantiates the type based on the given Java type. + * + * @param javaType The Java type of the JPA model type. + */ + protected AbstractType(Class javaType) { + this( javaType, javaType != null ? javaType.getName() : null ); + } + + /** + * Instantiates the type based on the given Java type. + * + * @param javaType + * @param typeName + */ + protected AbstractType(Class javaType, String typeName) { this.javaType = javaType; + this.typeName = typeName == null ? "unknown" : typeName; } - public Class getJavaType() { - return javaType; - } + /** + * {@inheritDoc} + *

+ * IMPL NOTE : The Hibernate version may return {@code null} here in the case of either dynamic models or + * entity classes mapped multiple times using entity-name. In these cases, the {@link #getTypeName()} value + * should be used. + */ + @Override + public Class getJavaType() { + return javaType; + } + + /** + * Obtains the type name. See notes on {@link #getJavaType()} for details + * + * @return The type name + */ + public String getTypeName() { + return typeName; + } } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AttributeFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AttributeFactory.java old mode 100644 new mode 100755 index d3156df97d..52fd1cddc3 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AttributeFactory.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/AttributeFactory.java @@ -88,12 +88,12 @@ public class AttributeFactory { // hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel. LOG.tracef( "Skipping synthetic property %s(%s)", - ownerType.getJavaType().getName(), + ownerType.getTypeName(), property.getName() ); return null; } - LOG.trace("Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]"); + LOG.trace("Building attribute [" + ownerType.getTypeName() + "." + property.getName() + "]"); final AttributeContext attributeContext = wrap( ownerType, property ); final AttributeMetadata attributeMetadata = determineAttributeMetadata( attributeContext, NORMAL_MEMBER_RESOLVER ); @@ -141,7 +141,7 @@ public class AttributeFactory { */ @SuppressWarnings({ "unchecked" }) public SingularAttributeImpl buildIdAttribute(AbstractIdentifiableType ownerType, Property property) { - LOG.trace("Building identifier attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]"); + LOG.trace("Building identifier attribute [" + ownerType.getTypeName() + "." + property.getName() + "]"); final AttributeContext attributeContext = wrap( ownerType, property ); final SingularAttributeMetadata attributeMetadata = (SingularAttributeMetadata) determineAttributeMetadata( attributeContext, IDENTIFIER_MEMBER_RESOLVER ); @@ -167,7 +167,7 @@ public class AttributeFactory { */ @SuppressWarnings({ "unchecked" }) public SingularAttributeImpl buildVersionAttribute(AbstractIdentifiableType ownerType, Property property) { - LOG.trace("Building version attribute [ownerType.getJavaType().getName()" + "." + "property.getName()]"); + LOG.trace("Building version attribute [ownerType.getTypeName()" + "." + "property.getName()]"); final AttributeContext attributeContext = wrap( ownerType, property ); final SingularAttributeMetadata attributeMetadata = (SingularAttributeMetadata) determineAttributeMetadata( attributeContext, VERSION_MEMBER_RESOLVER ); @@ -234,11 +234,11 @@ public class AttributeFactory { } } - private EntityMetamodel getDeclarerEntityMetamodel(IdentifiableType ownerType) { + private EntityMetamodel getDeclarerEntityMetamodel(AbstractIdentifiableType ownerType) { final Type.PersistenceType persistenceType = ownerType.getPersistenceType(); if ( persistenceType == Type.PersistenceType.ENTITY) { return context.getSessionFactory() - .getEntityPersister( ownerType.getJavaType().getName() ) + .getEntityPersister( ownerType.getTypeName() ) .getEntityMetamodel(); } else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS) { @@ -553,6 +553,9 @@ public class AttributeFactory { ? Attribute.PersistentAttributeType.ONE_TO_ONE : Attribute.PersistentAttributeType.MANY_TO_ONE; } + else if (MapMember.class.isInstance( member )) { + return Attribute.PersistentAttributeType.MANY_TO_ONE; // curious to see how this works for non-annotated methods + } else { return ( (Method) member ).getAnnotation( OneToOne.class ) != null ? Attribute.PersistentAttributeType.ONE_TO_ONE @@ -585,6 +588,9 @@ public class AttributeFactory { else if ( Method.class.isInstance( member ) ) { declaredType = ( (Method) member ).getReturnType(); } + else if ( MapMember.class.isInstance( member ) ) { + declaredType = ((MapMember) member).getType(); + } else { throw new IllegalArgumentException( "Cannot determine java-type from given member [" + member + "]" ); } @@ -844,14 +850,21 @@ public class AttributeFactory { } } - public static ParameterizedType getSignatureType(Member member) { - final java.lang.reflect.Type type = Field.class.isInstance( member ) - ? ( ( Field ) member ).getGenericType() - : ( ( Method ) member ).getGenericReturnType(); - //this is a raw type - if ( type instanceof Class ) return null; - return (ParameterizedType) type; - } + public static ParameterizedType getSignatureType(Member member) { + final java.lang.reflect.Type type; + if (Field.class.isInstance( member )) { + type = ( ( Field ) member ).getGenericType(); + } + else if ( Method.class.isInstance( member ) ) { + type = ( ( Method ) member ).getGenericReturnType(); + } + else { + type = ( (MapMember) member ).getType(); + } + //this is a raw type + if ( type instanceof Class ) return null; + return (ParameterizedType) type; + } public static PluralAttribute.CollectionType determineCollectionType(Class javaType) { if ( java.util.List.class.isAssignableFrom( javaType ) ) { @@ -871,11 +884,16 @@ public class AttributeFactory { } } - public static boolean isManyToMany(Member member) { - return Field.class.isInstance( member ) - ? ( (Field) member ).getAnnotation( ManyToMany.class ) != null - : ( (Method) member ).getAnnotation( ManyToMany.class ) != null; - } + public static boolean isManyToMany(Member member) { + if ( Field.class.isInstance( member ) ) { + return ( (Field) member ).getAnnotation( ManyToMany.class ) != null; + } + else if ( Method.class.isInstance( member ) ) { + return ( (Method) member ).getAnnotation( ManyToMany.class ) != null; + } + + return false; + } private final MemberResolver EMBEDDED_MEMBER_RESOLVER = new MemberResolver() { /** @@ -897,7 +915,7 @@ public class AttributeFactory { * {@inheritDoc} */ public Member resolveMember(AttributeContext attributeContext) { - final IdentifiableType identifiableType = (IdentifiableType) attributeContext.getOwnerType(); + final AbstractIdentifiableType identifiableType = (AbstractIdentifiableType) attributeContext.getOwnerType(); final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( identifiableType ); if ( ! entityMetamodel.getIdentifierProperty().isVirtual() ) { throw new IllegalArgumentException( "expecting IdClass mapping" ); @@ -931,7 +949,7 @@ public class AttributeFactory { } else if ( Type.PersistenceType.ENTITY == persistenceType || Type.PersistenceType.MAPPED_SUPERCLASS == persistenceType ) { - final IdentifiableType identifiableType = (IdentifiableType) ownerType; + final AbstractIdentifiableType identifiableType = (AbstractIdentifiableType) ownerType; final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( identifiableType ); final String propertyName = property.getName(); final Integer index = entityMetamodel.getPropertyIndexOrNull( propertyName ); @@ -953,7 +971,7 @@ public class AttributeFactory { private final MemberResolver IDENTIFIER_MEMBER_RESOLVER = new MemberResolver() { public Member resolveMember(AttributeContext attributeContext) { - final IdentifiableType identifiableType = (IdentifiableType) attributeContext.getOwnerType(); + final AbstractIdentifiableType identifiableType = (AbstractIdentifiableType) attributeContext.getOwnerType(); final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( identifiableType ); if ( ! attributeContext.getPropertyMapping().getName() .equals( entityMetamodel.getIdentifierProperty().getName() ) ) { @@ -966,7 +984,7 @@ public class AttributeFactory { private final MemberResolver VERSION_MEMBER_RESOLVER = new MemberResolver() { public Member resolveMember(AttributeContext attributeContext) { - final IdentifiableType identifiableType = (IdentifiableType) attributeContext.getOwnerType(); + final AbstractIdentifiableType identifiableType = (AbstractIdentifiableType) attributeContext.getOwnerType(); final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( identifiableType ); final String versionPropertyName = attributeContext.getPropertyMapping().getName(); if ( ! versionPropertyName.equals( entityMetamodel.getVersionProperty().getName() ) ) { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EmbeddableTypeImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EmbeddableTypeImpl.java index cf4660df23..662ae99a68 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EmbeddableTypeImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EmbeddableTypeImpl.java @@ -37,7 +37,7 @@ public class EmbeddableTypeImpl private final ComponentType hibernateType; public EmbeddableTypeImpl(Class javaType, AbstractManagedType parent, ComponentType hibernateType) { - super( javaType, null ); + super( javaType, null, null ); this.parent = parent; this.hibernateType = hibernateType; } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EntityTypeImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EntityTypeImpl.java index 0f900427e6..d4ff574337 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EntityTypeImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/EntityTypeImpl.java @@ -1,8 +1,10 @@ /* - * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2009, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,9 +22,12 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.jpa.internal.metamodel; + import java.io.Serializable; import javax.persistence.metamodel.EntityType; +import org.hibernate.mapping.PersistentClass; + /** * Defines the Hibernate implementation of the JPA {@link EntityType} contract. * @@ -34,14 +39,15 @@ public class EntityTypeImpl implements EntityType, Serializable { private final String jpaEntityName; - public EntityTypeImpl( - Class javaType, - AbstractIdentifiableType superType, - String jpaEntityName, - boolean hasIdentifierProperty, - boolean isVersioned) { - super( javaType, superType, hasIdentifierProperty, isVersioned ); - this.jpaEntityName = jpaEntityName; + public EntityTypeImpl(Class javaType, AbstractIdentifiableType superType, PersistentClass persistentClass) { + super( + javaType, + persistentClass.getEntityName(), + superType, + persistentClass.hasIdentifierProperty(), + persistentClass.isVersioned() + ); + this.jpaEntityName = persistentClass.getJpaEntityName(); } public String getName() { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MapMember.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MapMember.java new file mode 100755 index 0000000000..1f66c166e3 --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MapMember.java @@ -0,0 +1,39 @@ +package org.hibernate.jpa.internal.metamodel; + +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; + +/** + * Acts as a virtual Member definition for dynamic (Map-based) models. + * + * @author Brad Koehn + */ +public class MapMember implements Member { + private String name; + private final Class type; + + public MapMember(String name, Class type) { + this.name = name; + this.type = type; + } + + public Class getType() { + return type; + } + + public int getModifiers() { + return Modifier.PUBLIC; + } + + public boolean isSynthetic() { + return false; + } + + public String getName() { + return name; + } + + public Class getDeclaringClass() { + return null; + } +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MappedSuperclassTypeImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MappedSuperclassTypeImpl.java index 9f3fcd5bbd..a6448ceb33 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MappedSuperclassTypeImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MappedSuperclassTypeImpl.java @@ -1,16 +1,42 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2009, 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ package org.hibernate.jpa.internal.metamodel; + import javax.persistence.metamodel.MappedSuperclassType; +import org.hibernate.mapping.MappedSuperclass; + /** * @author Emmanuel Bernard + * @author Steve Ebersole */ public class MappedSuperclassTypeImpl extends AbstractIdentifiableType implements MappedSuperclassType { public MappedSuperclassTypeImpl( Class javaType, - AbstractIdentifiableType superType, - boolean hasIdentifierProperty, - boolean versioned) { - super( javaType, superType, hasIdentifierProperty, versioned ); + MappedSuperclass mappedSuperclass, + AbstractIdentifiableType superType) { + super( javaType, null, superType, mappedSuperclass.hasIdentifierProperty(), mappedSuperclass.isVersioned() ); } public PersistenceType getPersistenceType() { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java old mode 100644 new mode 100755 index 876da1ea98..c8caed32ab --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetadataContext.java @@ -1,8 +1,10 @@ /* - * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -21,6 +23,10 @@ */ package org.hibernate.jpa.internal.metamodel; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.IdentifiableType; +import javax.persistence.metamodel.MappedSuperclassType; +import javax.persistence.metamodel.SingularAttribute; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; @@ -30,17 +36,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import javax.persistence.metamodel.Attribute; -import javax.persistence.metamodel.IdentifiableType; -import javax.persistence.metamodel.MappedSuperclassType; -import javax.persistence.metamodel.SingularAttribute; import org.jboss.logging.Logger; import org.hibernate.annotations.common.AssertionFailure; -import org.hibernate.jpa.internal.EntityManagerMessageLogger; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.jpa.internal.EntityManagerMessageLogger; import org.hibernate.mapping.Component; import org.hibernate.mapping.KeyValue; import org.hibernate.mapping.MappedSuperclass; @@ -183,7 +185,11 @@ class MetadataContext { return entityTypesByEntityName.get( entityName ); } - @SuppressWarnings({ "unchecked" }) + public Map> getEntityTypesByEntityName() { + return Collections.unmodifiableMap( entityTypesByEntityName ); + } + + @SuppressWarnings({ "unchecked" }) public void wrapUp() { LOG.trace("Wrapping up metadata context..."); //we need to process types from superclasses to subclasses diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java old mode 100644 new mode 100755 index d8502b05d2..5306889b97 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java @@ -21,21 +21,17 @@ */ package org.hibernate.jpa.internal.metamodel; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.mapping.MappedSuperclass; +import org.hibernate.mapping.PersistentClass; + import java.io.Serializable; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; -import javax.persistence.metamodel.EmbeddableType; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.ManagedType; -import javax.persistence.metamodel.MappedSuperclassType; -import javax.persistence.metamodel.Metamodel; - -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.mapping.MappedSuperclass; -import org.hibernate.mapping.PersistentClass; +import javax.persistence.metamodel.*; /** * Hibernate implementation of the JPA {@link Metamodel} contract. @@ -47,6 +43,7 @@ public class MetamodelImpl implements Metamodel, Serializable { private final Map,EntityTypeImpl> entities; private final Map, EmbeddableTypeImpl> embeddables; private final Map, MappedSuperclassType> mappedSuperclassTypeMap; + private final Map> entityTypesByEntityName; /** * Build the metamodel using the information from the collection of Hibernate @@ -81,12 +78,10 @@ public class MetamodelImpl implements Metamodel, Serializable { MetadataContext context = new MetadataContext( sessionFactory, ignoreUnsupported ); while ( persistentClasses.hasNext() ) { PersistentClass pc = persistentClasses.next(); - if ( pc.getMappedClass() != null ) { - locateOrBuildEntityType( pc, context ); - } + locateOrBuildEntityType( pc, context ); } context.wrapUp(); - return new MetamodelImpl( context.getEntityTypeMap(), context.getEmbeddableTypeMap(), context.getMappedSuperclassTypeMap() ); + return new MetamodelImpl( context.getEntityTypeMap(), context.getEmbeddableTypeMap(), context.getMappedSuperclassTypeMap(), context.getEntityTypesByEntityName() ); } private static EntityTypeImpl locateOrBuildEntityType(PersistentClass persistentClass, MetadataContext context) { @@ -116,11 +111,10 @@ public class MetamodelImpl implements Metamodel, Serializable { EntityTypeImpl entityType = new EntityTypeImpl( javaType, superType, - persistentClass.getJpaEntityName(), - persistentClass.hasIdentifierProperty(), - persistentClass.isVersioned() + persistentClass ); - context.registerEntityType( persistentClass, entityType ); + + context.registerEntityType( persistentClass, entityType ); context.popEntityWorkedOn(persistentClass); return entityType; } @@ -136,8 +130,9 @@ public class MetamodelImpl implements Metamodel, Serializable { //TODO remove / reduce @SW scope @SuppressWarnings( "unchecked" ) - private static MappedSuperclassTypeImpl buildMappedSuperclassType(MappedSuperclass mappedSuperclass, - MetadataContext context) { + private static MappedSuperclassTypeImpl buildMappedSuperclassType( + MappedSuperclass mappedSuperclass, + MetadataContext context) { final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass(); AbstractIdentifiableType superType = superMappedSuperclass == null ? null @@ -152,9 +147,8 @@ public class MetamodelImpl implements Metamodel, Serializable { final Class javaType = mappedSuperclass.getMappedClass(); MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl( javaType, - superType, - mappedSuperclass.hasIdentifierProperty(), - mappedSuperclass.isVersioned() + mappedSuperclass, + superType ); context.registerMappedSuperclassType( mappedSuperclass, mappedSuperclassType ); return mappedSuperclassType; @@ -170,10 +164,12 @@ public class MetamodelImpl implements Metamodel, Serializable { private MetamodelImpl( Map, EntityTypeImpl> entities, Map, EmbeddableTypeImpl> embeddables, - Map, MappedSuperclassType> mappedSuperclassTypeMap) { + Map, MappedSuperclassType> mappedSuperclassTypeMap, + Map> entityTypesByEntityName) { this.entities = entities; this.embeddables = embeddables; this.mappedSuperclassTypeMap = mappedSuperclassTypeMap; + this.entityTypesByEntityName = entityTypesByEntityName; } @Override @@ -226,7 +222,7 @@ public class MetamodelImpl implements Metamodel, Serializable { @Override public Set> getEntities() { - return new HashSet>( entities.values() ); + return new HashSet>( entityTypesByEntityName.values() ); } @Override