HHH-11859 - Fix PropertyAccessException on update of detached audited entity.
This commit is contained in:
parent
adb9024c28
commit
6fb4ec0e02
|
@ -17,6 +17,8 @@ import org.hibernate.envers.internal.entities.mapper.id.IdMapper;
|
||||||
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
||||||
import org.hibernate.envers.internal.tools.EntityTools;
|
import org.hibernate.envers.internal.tools.EntityTools;
|
||||||
import org.hibernate.envers.internal.tools.query.Parameters;
|
import org.hibernate.envers.internal.tools.query.Parameters;
|
||||||
|
import org.hibernate.internal.util.compare.EqualsHelper;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
|
@ -81,8 +83,37 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean checkModified(SessionImplementor session, Object newObj, Object oldObj) {
|
protected boolean checkModified(SessionImplementor session, Object newObj, Object oldObj) {
|
||||||
//noinspection SimplifiableConditionalExpression
|
if ( nonInsertableFake ) {
|
||||||
return nonInsertableFake ? false : !EntityTools.entitiesEqual( session, referencedEntityName, newObj, oldObj );
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( newObj == null || oldObj == null || newObj.getClass().equals( oldObj.getClass() ) ) {
|
||||||
|
return !EntityTools.entitiesEqual( session, referencedEntityName, newObj, oldObj );
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is a chance that oldObj may reference the identifier of the old entity rather
|
||||||
|
// than the entity instance itself. This happens under Session#update with a detached
|
||||||
|
// entity because the database snapshot that is used to derive the prior state doesn't
|
||||||
|
// return the entity instances of the to-one associations but only the identifier.
|
||||||
|
//
|
||||||
|
// So here we assume the method was supplied the id and we ask the persister to verify
|
||||||
|
// if the value is the identifier type. If not, we assume its the entity type and
|
||||||
|
// therefore resolve the identifier from the entity directly prior to simply then
|
||||||
|
// doing the identifier comparison.
|
||||||
|
|
||||||
|
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister( referencedEntityName );
|
||||||
|
|
||||||
|
Object resolvedNewObjectId = newObj;
|
||||||
|
if ( !persister.getIdentifierType().getReturnedClass().isInstance( newObj ) ) {
|
||||||
|
resolvedNewObjectId = EntityTools.getIdentifier( session, referencedEntityName, newObj );
|
||||||
|
}
|
||||||
|
|
||||||
|
Object resolvedOldObjectId = oldObj;
|
||||||
|
if ( !persister.getIdentifierType().getReturnedClass().isInstance( oldObj ) ) {
|
||||||
|
resolvedOldObjectId = EntityTools.getIdentifier( session, referencedEntityName, oldObj );
|
||||||
|
}
|
||||||
|
|
||||||
|
return !EqualsHelper.areEqual( resolvedNewObjectId, resolvedOldObjectId );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue