HHH-4848 partial implementation of @IdClass support in derivedidentity (example 1 case a of the spec)

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18692 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-02-04 17:54:05 +00:00
parent cffff168b3
commit 252299cfee
13 changed files with 211 additions and 73 deletions

View File

@ -55,6 +55,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
private Map<String, JoinTable> currentPropertyJoinTableOverride;
private String path;
private ExtendedMappings mappings;
private Boolean isInIdClass;
public AbstractPropertyHolder(
@ -66,6 +67,15 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
buildHierarchyColumnOverride( clazzToProcess );
}
public boolean isInIdClass() {
return isInIdClass != null ? isInIdClass : parent != null ? parent.isInIdClass() : false;
}
public void setInIdClass(Boolean isInIdClass) {
this.isInIdClass = isInIdClass;
}
public String getPath() {
return path;
}

View File

@ -701,6 +701,7 @@ public final class
HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
entityBinder.setIgnoreIdAnnotations( true );
propertyHolder.setInIdClass( true );
bindId(
generatorType,
generator,
@ -716,6 +717,7 @@ public final class
mappings,
inheritanceStatePerClass
);
propertyHolder.setInIdClass( null );
inferredData = new PropertyPreloadedData(
propertyAccessor, "_identifierMapper", compositeClass
);
@ -728,7 +730,9 @@ public final class
entityBinder,
true,
true,
false, mappings, inheritanceStatePerClass
false,
mappings,
inheritanceStatePerClass
);
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
persistentClass.setIdentifierMapper( mapper );
@ -1164,7 +1168,7 @@ public final class
* strategy is used
* @param propertyContainer Metadata about a class and its properties
* @param mappings Mapping meta data
* @return the number of id properties found while iterating the elements of {@code annoatedClass} using
* @return the number of id properties found while iterating the elements of {@code annotatedClass} using
* the determined access strategy, {@code false} otherwise.
*/
static int addElementsOfClass(
@ -1206,6 +1210,9 @@ public final class
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
annElts.add( 0, propertyAnnotatedElement );
if ( element.isAnnotationPresent( ManyToOne.class ) || element.isAnnotationPresent( OneToOne.class ) ) {
mappings.addToOneAndIdProperty( entity, propertyAnnotatedElement );
}
idPropertyCounter++;
}
else {
@ -1713,15 +1720,15 @@ public final class
//FIXME do the overrideColumnFromMapsIdProperty here and force the idclass type to look like an @embedded
//Overrides from @MapsId if needed
boolean isOverridden = false;
if ( isId || propertyHolder.isOrWithinEmbeddedId() ) {
if ( isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass() ) {
Ejb3Column[] oldColumns = columns;
columns = columnsBuilder.overrideColumnFromMapsIdProperty(isId);
columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty(isId);
isOverridden = oldColumns != columns;
}
if ( isComponent ) {
String referencedEntityName = null;
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyAnnotatedWithMapsId(
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
isId, propertyHolder, property.getName(), mappings
);
referencedEntityName = mapsIdProperty.getClassOrElementName();
@ -1761,7 +1768,7 @@ public final class
propertyBinder.setLazy( lazy );
propertyBinder.setColumns( columns );
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyAnnotatedWithMapsId(
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
isId, propertyHolder, property.getName(), mappings
);
propertyBinder.setReferencedEntityName( mapsIdProperty.getClassOrElementName() );
@ -1771,7 +1778,7 @@ public final class
}
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyAnnotatedWithMapsId(
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
isId, propertyHolder, property.getName(), mappings
);
HashMap<String, IdGenerator> localGenerators = (HashMap<String, IdGenerator>) classGenerators.clone();
@ -2021,7 +2028,8 @@ public final class
}
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData, PropertyData baseInferredData,
PropertyHolder propertyHolder, PropertyData inferredData,
PropertyData baseInferredData, //base inferred data correspond to the entity reproducing inferredData's properties (ie IdClass)
AccessType propertyAccessor, boolean isNullable, EntityBinder entityBinder,
boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings,
Map<XClass, InheritanceState> inheritanceStatePerClass
@ -2045,14 +2053,17 @@ public final class
XClass returnedClassOrElement = inferredData.getClassOrElement();
List<PropertyData> baseClassElements = null;
Map<String, PropertyData> orderedBaseClassElements = new HashMap<String, PropertyData>();
XClass baseReturnedClassOrElement;
if(baseInferredData != null)
{
if(baseInferredData != null) {
baseClassElements = new ArrayList<PropertyData>();
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
bindTypeDefs(baseReturnedClassOrElement, mappings);
PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement, entityXClass );
addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
for (PropertyData element : baseClassElements) {
orderedBaseClassElements.put( element.getPropertyName(), element );
}
}
//embeddable elements can have type defs
@ -2069,9 +2080,24 @@ public final class
superClass = superClass.getSuperclass();
}
if ( baseClassElements != null ) {
if ( !hasIdClassAnnotations( entityXClass ) ) {
//useful to avoid breaking pre JPA 2 mappings
if ( !hasAnnotationsOnIdClass( entityXClass ) ) {
for ( int i = 0; i < classElements.size(); i++ ) {
classElements.set( i, baseClassElements.get( i ) ); //this works since they are in the same order
final PropertyData idClassPropertyData = classElements.get( i );
final PropertyData entityPropertyData = orderedBaseClassElements.get( idClassPropertyData.getPropertyName() );
if ( propertyHolder.isInIdClass() ) {
if ( entityPropertyData.getProperty().isAnnotationPresent( ManyToOne.class )
|| entityPropertyData.getProperty().isAnnotationPresent( OneToOne.class ) ) {
//don't replace here as we need to use the actual original return type
//the annotation overriding will be dealt with by a mechanism similar to @MapsId
}
else {
classElements.set( i, entityPropertyData ); //this works since they are in the same order
}
}
else {
classElements.set( i, entityPropertyData ); //this works since they are in the same order
}
}
}
}
@ -2087,10 +2113,9 @@ public final class
XProperty property = propertyAnnotatedElement.getProperty();
if(property.isAnnotationPresent(GeneratedValue.class) &&
property.isAnnotationPresent(Id.class))
{
property.isAnnotationPresent(Id.class) ) {
//clone classGenerator and override with local values
HashMap<String, IdGenerator> localGenerators = (HashMap<String, IdGenerator>) new HashMap<String, IdGenerator>();
HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
localGenerators.putAll( buildLocalGenerators( property, mappings ) );
GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
@ -2647,10 +2672,10 @@ public final class
return inheritanceStatePerClass;
}
private static boolean hasIdClassAnnotations(XClass idClass)
private static boolean hasAnnotationsOnIdClass(XClass idClass)
{
if(idClass.getAnnotation(Embeddable.class) != null)
return true;
// if(idClass.getAnnotation(Embeddable.class) != null)
// return true;
List<XProperty> properties = idClass.getDeclaredProperties( XClass.ACCESS_FIELD );
for ( XProperty property : properties ) {

View File

@ -65,7 +65,6 @@ import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.Cache;
@ -158,6 +157,7 @@ public class AnnotationConfiguration extends Configuration {
private boolean isDefaultProcessed = false;
private boolean isValidatorNotPresentLogged;
private Map<XClass,Map<String,PropertyData>> propertiesAnnotatedWithMapsId;
private Map<XClass,Map<String,PropertyData>> propertiesAnnotatedWithIdAndToOne;
public AnnotationConfiguration() {
super();
@ -297,6 +297,7 @@ public class AnnotationConfiguration extends Configuration {
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap<String, AnyMetaDef>();
propertiesAnnotatedWithMapsId = new HashMap<XClass, Map<String,PropertyData>>();
propertiesAnnotatedWithIdAndToOne = new HashMap<XClass, Map<String,PropertyData>>();
reflectionManager = new JavaReflectionManager();
( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new JPAMetadataProvider() );
@ -1293,6 +1294,20 @@ public class AnnotationConfiguration extends Configuration {
map.put( property.getProperty().getAnnotation( MapsId.class ).value(), property );
}
public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String propertyName) {
final Map<String, PropertyData> map = propertiesAnnotatedWithIdAndToOne.get( entityType );
return map == null ? null : map.get( propertyName );
}
public void addToOneAndIdProperty(XClass entityType, PropertyData property) {
Map<String, PropertyData> map = propertiesAnnotatedWithIdAndToOne.get( entityType );
if (map == null) {
map = new HashMap<String, PropertyData>();
propertiesAnnotatedWithIdAndToOne.put( entityType, map );
}
map.put( property.getPropertyName(), property );
}
private Boolean useNewGeneratorMappings;
@SuppressWarnings({ "UnnecessaryUnboxing" })

View File

@ -652,7 +652,7 @@ public class BinderHelper {
return StringHelper.qualify( holder.getPath(), property.getPropertyName() );
}
static PropertyData getPropertyAnnotatedWithMapsId(boolean isId, PropertyHolder propertyHolder, String propertyName, ExtendedMappings mappings) {
static PropertyData getPropertyOverriddenByMapperOrMapsId(boolean isId, PropertyHolder propertyHolder, String propertyName, ExtendedMappings mappings) {
final XClass persistentXClass;
try {
persistentXClass = mappings.getReflectionManager()
@ -661,8 +661,12 @@ public class BinderHelper {
catch ( ClassNotFoundException e ) {
throw new AssertionFailure( "PersistentClass name cannot be converted into a Class", e);
}
String propertyPath = isId ? "" : propertyName;
final PropertyData annotatedWithMapsId = mappings.getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath );
return annotatedWithMapsId;
if ( propertyHolder.isInIdClass() ) {
return mappings.getPropertyAnnotatedWithIdAndToOne( persistentXClass, propertyName );
}
else {
String propertyPath = isId ? "" : propertyName;
return mappings.getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath );
}
}
}

View File

@ -11,12 +11,10 @@ import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.JoinColumnsOrFormulas;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.annotations.EntityBinder;
import org.hibernate.cfg.annotations.Nullability;
@ -183,15 +181,13 @@ class ColumnsBuilder {
return joinColumns;
}
Ejb3Column[] overrideColumnFromMapsIdProperty(boolean isId) {
Ejb3Column[] overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
Ejb3Column[] result = columns;
final PropertyData annotatedWithMapsId = BinderHelper.getPropertyAnnotatedWithMapsId( isId, propertyHolder, property.getName(), mappings );
final PropertyData annotatedWithMapsId = BinderHelper.getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), mappings );
if ( annotatedWithMapsId != null ) {
result = buildExplicitJoinColumns( annotatedWithMapsId.getProperty(), annotatedWithMapsId );
if (result == null) {
result = buildDefaultJoinColumnsForXToOne( annotatedWithMapsId.getProperty(), annotatedWithMapsId);
// throw new UnsupportedOperationException( "Implicit @JoinColumn is not supported on @MapsId properties: "
// + annotatedWithMapsId.getDeclaringClass() + " " + annotatedWithMapsId.getPropertyName() );
}
}
return result;

View File

@ -188,4 +188,12 @@ public interface ExtendedMappings extends Mappings {
* @return True if the new generators should be used, false otherwise.
*/
public boolean useNewGeneratorMappings();
/**
* Return the property annotated with @ToOne and @Id if any.
* Null otherwise
*/
public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String propertyName);
void addToOneAndIdProperty(XClass entity, PropertyData property);
}

View File

@ -89,4 +89,8 @@ public interface PropertyHolder {
String getEntityName();
Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation);
boolean isInIdClass();
void setInIdClass(Boolean isInIdClass);
}

View File

@ -7,5 +7,5 @@ import java.io.Serializable;
*/
public class DependentId implements Serializable {
String name;
long empPK; // corresponds to PK type of Employee
long emp; // corresponds to PK type of Employee
}

View File

@ -1,6 +1,7 @@
package org.hibernate.test.annotations.derivedidentities.e1.a;
import org.hibernate.Session;
import org.hibernate.junit.FailureExpected;
import org.hibernate.test.annotations.TestCase;
import org.hibernate.test.util.SchemaUtil;
@ -10,36 +11,40 @@ import org.hibernate.test.util.SchemaUtil;
public class
DerivedIdentitySimpleParentIdClassDepTest extends TestCase {
@FailureExpected( jiraKey = "HHH-4848" )
public void testManyToOne() throws Exception {
// assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK", getCfg() ) );
// assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "empPK", getCfg() ) );
// Employee e = new Employee();
// e.empId = 1;
// e.empName = "Emmanuel";
// Session s = openSession( );
// s.getTransaction().begin();
// s.persist( e );
// Dependent d = new Dependent();
// d.emp = e;
// d.name = "Doggy";
// d.emp = e;
// s.persist( d );
// s.flush();
// s.clear();
// DependentId dId = new DependentId();
// dId.name = d.name;
// dId.empPK = d.emp.empId;
// d = (Dependent) s.get( Dependent.class, dId );
// assertEquals( e.empId, d.emp.empId );
// s.getTransaction().rollback();
// s.close();
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_empId", getCfg() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "emp", getCfg() ) );
Employee e = new Employee();
e.empId = 1;
e.empName = "Emmanuel";
e.nickname = "Manu";
Session s = openSession( );
s.getTransaction().begin();
s.persist( e );
Dependent d = new Dependent();
d.emp = e;
d.name = "Doggy";
d.emp = e;
s.persist( d );
s.flush();
s.clear();
DependentId dId = new DependentId();
dId.name = d.name;
dId.emp = d.emp.empId;
d = (Dependent) s.get( Dependent.class, dId );
assertEquals( e.empId, d.emp.empId );
assertEquals( e.empName, d.emp.empName );
assertEquals( e.nickname, d.emp.nickname );
s.getTransaction().rollback();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
//Dependent.class,
//Employee.class
Dependent.class,
Employee.class
};
}
}

View File

@ -11,4 +11,6 @@ public class Employee {
@Id
long empId;
String empName;
String nickname;
}

View File

@ -33,6 +33,7 @@ import org.hibernate.TransientObjectException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.ForeignKeys;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
@ -95,18 +96,26 @@ public class ForeignGenerator implements IdentifierGenerator, Configurable {
public Serializable generate(SessionImplementor sessionImplementor, Object object) {
Session session = ( Session ) sessionImplementor;
Object associatedObject = sessionImplementor.getFactory()
.getClassMetadata( entityName )
final ClassMetadata classMetadata = sessionImplementor.getFactory()
.getClassMetadata( entityName );
Object associatedObject = classMetadata
.getPropertyValue( object, propertyName, session.getEntityMode() );
if ( associatedObject == null ) {
throw new IdentifierGenerationException(
"attempted to assign id from null one-to-one property [" + getRole() + "]"
);
}
EntityType type = (EntityType) sessionImplementor.getFactory()
.getClassMetadata( entityName )
.getPropertyType( propertyName );
final Type uncheckedType = classMetadata
.getPropertyType( propertyName );
EntityType type;
if (uncheckedType instanceof EntityType) {
type = (EntityType) uncheckedType;
}
else {
//try identifier mapper
type = (EntityType) classMetadata.getPropertyType( "_identifierMapper." + propertyName );
}
Serializable id;
try {

View File

@ -30,6 +30,8 @@ import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.PropertyAccessException;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.VersionProperty;
import org.hibernate.tuple.StandardProperty;
@ -45,6 +47,8 @@ import org.hibernate.property.Setter;
import org.hibernate.proxy.ProxyFactory;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/**
@ -70,6 +74,9 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
private final ProxyFactory proxyFactory;
private final AbstractComponentType identifierMapperType;
public Type getIdentifierMapperType() {
return identifierMapperType;
}
/**
* Build an appropriate Getter for the given property.
@ -192,13 +199,27 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
else {
ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
id = copier.instantiate( getEntityMode() );
copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() );
final Object[] propertyValues = identifierMapperType.getPropertyValues( entity, getEntityMode() );
Type[] subTypes = identifierMapperType.getSubtypes();
Type[] copierSubTypes = copier.getSubtypes();
final int length = subTypes.length;
for ( int i = 0 ; i < length; i++ ) {
//JPA 2 in @IdClass points to the pk of the entity
if ( subTypes[i].isAssociationType() && ! copierSubTypes[i].isAssociationType()) {
final String associatedEntityName = ( ( EntityType ) subTypes[i] ).getAssociatedEntityName();
final EntityPersister entityPersister = getFactory().getEntityPersister(
associatedEntityName
);
propertyValues[i] = entityPersister.getIdentifier( propertyValues[i], getEntityMode() );
}
}
copier.setPropertyValues( id, propertyValues, getEntityMode() );
}
}
else {
id = idGetter.get( entity );
}
}
id = idGetter.get( entity );
}
}
try {
return (Serializable) id;
@ -229,7 +250,18 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
else if ( identifierMapperType != null ) {
ComponentType extractor = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
ComponentType copier = (ComponentType) identifierMapperType;
copier.setPropertyValues( entity, extractor.getPropertyValues( id, getEntityMode() ), getEntityMode() );
final Object[] propertyValues = extractor.getPropertyValues( id, getEntityMode() );
Type[] subTypes = identifierMapperType.getSubtypes();
Type[] copierSubTypes = copier.getSubtypes();
final int length = subTypes.length;
for ( int i = 0 ; i < length; i++ ) {
//JPA 2 in @IdClass points to the pk of the entity
if ( subTypes[i].isAssociationType() && ! copierSubTypes[i].isAssociationType() ) {
final String associatedEntityName = ( ( EntityType ) subTypes[i] ).getAssociatedEntityName();
//FIXME find the entity for the given id (propertyValue[i])
}
}
copier.setPropertyValues( entity, propertyValues, getEntityMode() );
}
}
@ -299,18 +331,27 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
}
public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException {
final int loc = propertyPath.indexOf('.');
final String basePropertyName = loc > 0
int loc = propertyPath.indexOf('.');
String basePropertyName = loc > 0
? propertyPath.substring( 0, loc )
: propertyPath;
final int index = entityMetamodel.getPropertyIndex( basePropertyName );
final Object baseValue = getPropertyValue( entity, index );
//final int index = entityMetamodel.getPropertyIndexOrNull( basePropertyName );
Integer index = entityMetamodel.getPropertyIndexOrNull( basePropertyName );
if (index == null) {
propertyPath = "_identifierMapper." + propertyPath;
loc = propertyPath.indexOf('.');
basePropertyName = loc > 0
? propertyPath.substring( 0, loc )
: propertyPath;
}
index = entityMetamodel.getPropertyIndexOrNull( basePropertyName );
final Object baseValue = getPropertyValue( entity, index.intValue() );
if ( loc > 0 ) {
if ( baseValue == null ) {
return null;
}
return getComponentValue(
(ComponentType) entityMetamodel.getPropertyTypes()[index],
(ComponentType) entityMetamodel.getPropertyTypes()[index.intValue()],
baseValue,
propertyPath.substring(loc+1)
);

View File

@ -307,7 +307,13 @@ public abstract class EntityType extends AbstractType implements AssociationType
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier();
}
else {
id = persister.getIdentifier(x, entityMode);
final Class mappedClass = persister.getMappedClass( entityMode );
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
id = persister.getIdentifier(x, entityMode);
}
else {
id = (Serializable) x;
}
}
return persister.getIdentifierType().getHashCode(id, entityMode, factory);
}
@ -321,13 +327,20 @@ public abstract class EntityType extends AbstractType implements AssociationType
return super.isEqual(x, y, entityMode);
}
final Class mappedClass = persister.getMappedClass( entityMode );
Serializable xid;
if (x instanceof HibernateProxy) {
xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
.getIdentifier();
}
else {
xid = persister.getIdentifier(x, entityMode);
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
xid = persister.getIdentifier(x, entityMode);
}
else {
//JPA 2 case where @IdClass contains the id and not the associated entity
xid = (Serializable) x;
}
}
Serializable yid;
@ -336,7 +349,13 @@ public abstract class EntityType extends AbstractType implements AssociationType
.getIdentifier();
}
else {
yid = persister.getIdentifier(y, entityMode);
if ( mappedClass.isAssignableFrom( y.getClass() ) ) {
yid = persister.getIdentifier(x, entityMode);
}
else {
//JPA 2 case where @IdClass contains the id and not the associated entity
yid = (Serializable) y;
}
}
return persister.getIdentifierType()