HHH-10251 - Memory Leak when using Reference Cached, bytecode enhanced Immutable Entities

This commit is contained in:
Steve Ebersole 2015-11-09 16:59:58 -06:00
parent 26048f220d
commit 0cc5e8d30f
2 changed files with 47 additions and 20 deletions

View File

@ -290,10 +290,10 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes(); ( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
} }
persistenceContext.getSession() getPersistenceContext().getSession()
.getFactory() .getFactory()
.getCustomEntityDirtinessStrategy() .getCustomEntityDirtinessStrategy()
.resetDirty( entity, getPersister(), (Session) persistenceContext.getSession() ); .resetDirty( entity, getPersister(), (Session) getPersistenceContext().getSession() );
} }
@Override @Override
@ -340,15 +340,14 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
@SuppressWarnings( {"SimplifiableIfStatement"}) @SuppressWarnings( {"SimplifiableIfStatement"})
private boolean isUnequivocallyNonDirty(Object entity) { private boolean isUnequivocallyNonDirty(Object entity) {
if (entity instanceof SelfDirtinessTracker) {
if(entity instanceof SelfDirtinessTracker) {
return ! ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes(); return ! ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes();
} }
final CustomEntityDirtinessStrategy customEntityDirtinessStrategy = final CustomEntityDirtinessStrategy customEntityDirtinessStrategy =
persistenceContext.getSession().getFactory().getCustomEntityDirtinessStrategy(); getPersistenceContext().getSession().getFactory().getCustomEntityDirtinessStrategy();
if ( customEntityDirtinessStrategy.canDirtyCheck( entity, getPersister(), (Session) persistenceContext.getSession() ) ) { if ( customEntityDirtinessStrategy.canDirtyCheck( entity, getPersister(), (Session) getPersistenceContext().getSession() ) ) {
return ! customEntityDirtinessStrategy.isDirty( entity, getPersister(), (Session) persistenceContext.getSession() ); return ! customEntityDirtinessStrategy.isDirty( entity, getPersister(), (Session) getPersistenceContext().getSession() );
} }
if ( getPersister().hasMutableProperties() ) { if ( getPersister().hasMutableProperties() ) {
@ -407,7 +406,7 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
} }
setStatus( Status.MANAGED ); setStatus( Status.MANAGED );
loadedState = getPersister().getPropertyValues( entity ); loadedState = getPersister().getPropertyValues( entity );
persistenceContext.getNaturalIdHelper().manageLocalNaturalIdCrossReference( getPersistenceContext().getNaturalIdHelper().manageLocalNaturalIdCrossReference(
persister, persister,
id, id,
loadedState, loadedState,

View File

@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.Serializable; import java.io.Serializable;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.UnsupportedLockAttemptException; import org.hibernate.UnsupportedLockAttemptException;
@ -51,8 +52,20 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
final boolean disableVersionIncrement, final boolean disableVersionIncrement,
final boolean lazyPropertiesAreUnfetched, final boolean lazyPropertiesAreUnfetched,
final PersistenceContext persistenceContext) { final PersistenceContext persistenceContext) {
this( status, loadedState, rowId, id, version, lockMode, existsInDatabase, this(
persister,disableVersionIncrement, lazyPropertiesAreUnfetched, null ); status,
loadedState,
rowId,
id,
version,
lockMode,
existsInDatabase,
persister,
disableVersionIncrement,
lazyPropertiesAreUnfetched,
// purposefully do not pass along the session/persistence-context : HHH-10251
null
);
} }
public ImmutableEntityEntry( public ImmutableEntityEntry(
@ -68,8 +81,20 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
final boolean lazyPropertiesAreUnfetched, final boolean lazyPropertiesAreUnfetched,
final PersistenceContext persistenceContext) { final PersistenceContext persistenceContext) {
super( status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister, super(
disableVersionIncrement, lazyPropertiesAreUnfetched, null ); status,
loadedState,
rowId,
id,
version,
lockMode,
existsInDatabase,
persister,
disableVersionIncrement,
lazyPropertiesAreUnfetched,
// purposefully do not pass along the session/persistence-context : HHH-10251
null
);
} }
/** /**
@ -98,13 +123,15 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
@Override @Override
public void setLockMode(LockMode lockMode) { public void setLockMode(LockMode lockMode) {
switch ( lockMode ) {
switch(lockMode) { case NONE:
case NONE : case READ: case READ: {
setCompressedValue( EnumState.LOCK_MODE, lockMode ); setCompressedValue( EnumState.LOCK_MODE, lockMode );
break; break;
default: }
throw new UnsupportedLockAttemptException("Lock mode not supported"); default: {
throw new UnsupportedLockAttemptException( "Lock mode not supported" );
}
} }
} }
@ -140,12 +167,13 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
ois.readBoolean(), ois.readBoolean(),
ois.readBoolean(), ois.readBoolean(),
ois.readBoolean(), ois.readBoolean(),
persistenceContext null
); );
} }
public PersistenceContext getPersistenceContext(){ @Override
return persistenceContext; public PersistenceContext getPersistenceContext() {
throw new AssertionFailure( "Session/PersistenceContext is not available from an ImmutableEntityEntry" );
} }
} }