diff --git a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java index 342616914091..de61d207e2cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EntityType.java @@ -352,7 +352,7 @@ public int getHashCode(Object x, SessionFactoryImplementor factory) { } else { final Class mappedClass = persister.getMappedClass(); - if ( mappedClass.isAssignableFrom( x.getClass() ) ) { + if ( mappedClass.isInstance( x ) ) { id = persister.getIdentifier( x, (SharedSessionContractImplementor) null ); } else { @@ -363,8 +363,15 @@ public int getHashCode(Object x, SessionFactoryImplementor factory) { } else { assert uniqueKeyPropertyName != null; + final Object uniqueKey; final Type keyType = persister.getPropertyType( uniqueKeyPropertyName ); - return keyType.getHashCode( x, factory ); + if ( keyType.getReturnedClass().isInstance( x ) ) { + uniqueKey = x; + } + else { + uniqueKey = persister.getPropertyValue( x, uniqueKeyPropertyName ); + } + return keyType.getHashCode( uniqueKey, factory ); } } @@ -379,39 +386,62 @@ public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) { } final EntityPersister persister = getAssociatedEntityPersister( factory ); - final Class mappedClass = persister.getMappedClass(); - Object xid; - final LazyInitializer lazyInitializerX = extractLazyInitializer( x ); - if ( lazyInitializerX != null ) { - xid = lazyInitializerX.getInternalIdentifier(); - } - else { - if ( mappedClass.isAssignableFrom( x.getClass() ) ) { - xid = persister.getIdentifier( x, (SharedSessionContractImplementor) null ); + if ( isReferenceToPrimaryKey() ) { + final Class mappedClass = persister.getMappedClass(); + Object xid; + final LazyInitializer lazyInitializerX = extractLazyInitializer( x ); + if ( lazyInitializerX != null ) { + xid = lazyInitializerX.getInternalIdentifier(); } else { - //JPA 2 case where @IdClass contains the id and not the associated entity - xid = x; + if ( mappedClass.isInstance( x ) ) { + xid = persister.getIdentifier( x, (SharedSessionContractImplementor) null ); + } + else { + //JPA 2 case where @IdClass contains the id and not the associated entity + xid = x; + } + } + + Object yid; + final LazyInitializer lazyInitializerY = extractLazyInitializer( y ); + if ( lazyInitializerY != null ) { + yid = lazyInitializerY.getInternalIdentifier(); + } + else { + if ( mappedClass.isInstance( y ) ) { + yid = persister.getIdentifier( y, (SharedSessionContractImplementor) null ); + } + else { + //JPA 2 case where @IdClass contains the id and not the associated entity + yid = y; + } } - } - Object yid; - final LazyInitializer lazyInitializerY = extractLazyInitializer( y ); - if ( lazyInitializerY != null ) { - yid = lazyInitializerY.getInternalIdentifier(); + // Check for reference equality first as the type-specific checks by IdentifierType are sometimes non-trivial + return ( xid == yid ) || persister.getIdentifierType().isEqual( xid, yid, factory ); } else { - if ( mappedClass.isAssignableFrom( y.getClass() ) ) { - yid = persister.getIdentifier( y, (SharedSessionContractImplementor) null ); + assert uniqueKeyPropertyName != null; + final Object xUniqueKey; + final Type keyType = persister.getPropertyType( uniqueKeyPropertyName ); + if ( keyType.getReturnedClass().isInstance( x ) ) { + xUniqueKey = x; } else { - //JPA 2 case where @IdClass contains the id and not the associated entity - yid = y; + xUniqueKey = persister.getPropertyValue( x, uniqueKeyPropertyName ); } - } - // Check for reference equality first as the type-specific checks by IdentifierType are sometimes non-trivial - return ( xid == yid ) || persister.getIdentifierType().isEqual( xid, yid, factory ); + final Object yUniqueKey; + if ( keyType.getReturnedClass().isInstance( y ) ) { + yUniqueKey = y; + } + else { + yUniqueKey = persister.getPropertyValue( y, uniqueKeyPropertyName ); + } + return (xUniqueKey == yUniqueKey) + || keyType.isEqual( xUniqueKey, yUniqueKey, factory ); + } } /**