HHH-13634 : PersistenceContext can get cleared before load completes using StatelessSessionImpl

(cherry picked from commit 42de569a37)
This commit is contained in:
Gail Badner 2019-10-16 11:19:13 -07:00 committed by gbadner
parent dd92c0f9a8
commit 04eba997e2
1 changed files with 15 additions and 6 deletions

View File

@ -283,11 +283,12 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
boolean nullable) throws HibernateException { boolean nullable) throws HibernateException {
checkOpen(); checkOpen();
EntityPersister persister = getFactory().getMetamodel().entityPersister( entityName ); final EntityPersister persister = getFactory().getMetamodel().entityPersister( entityName );
final EntityKey entityKey = generateEntityKey( id, persister ); final EntityKey entityKey = generateEntityKey( id, persister );
// first, try to load it from the temp PC associated to this SS // first, try to load it from the temp PC associated to this SS
Object loaded = temporaryPersistenceContext.getEntity( entityKey ); final PersistenceContext persistenceContext = getPersistenceContext();
Object loaded = persistenceContext.getEntity( entityKey );
if ( loaded != null ) { if ( loaded != null ) {
// we found it in the temp PC. Should indicate we are in the midst of processing a result set // we found it in the temp PC. Should indicate we are in the midst of processing a result set
// containing eager fetches via join fetch // containing eager fetches via join fetch
@ -307,7 +308,6 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
// if the entity defines a HibernateProxy factory, see if there is an // if the entity defines a HibernateProxy factory, see if there is an
// existing proxy associated with the PC - and if so, use it // existing proxy associated with the PC - and if so, use it
if ( persister.getEntityMetamodel().getTuplizer().getProxyFactory() != null ) { if ( persister.getEntityMetamodel().getTuplizer().getProxyFactory() != null ) {
final PersistenceContext persistenceContext = getPersistenceContext();
final Object proxy = persistenceContext.getProxy( entityKey ); final Object proxy = persistenceContext.getProxy( entityKey );
if ( proxy != null ) { if ( proxy != null ) {
@ -338,9 +338,9 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
} }
else { else {
if ( persister.hasProxy() ) { if ( persister.hasProxy() ) {
final Object existingProxy = getPersistenceContext().getProxy( entityKey ); final Object existingProxy = persistenceContext.getProxy( entityKey );
if ( existingProxy != null ) { if ( existingProxy != null ) {
return getPersistenceContext().narrowProxy( existingProxy, persister, entityKey, null ); return persistenceContext.narrowProxy( existingProxy, persister, entityKey, null );
} }
else { else {
return createProxy( entityKey ); return createProxy( entityKey );
@ -350,7 +350,16 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
} }
// otherwise immediately materialize it // otherwise immediately materialize it
return get( entityName, id );
// IMPLEMENTATION NOTE: increment/decrement the load count before/after getting the value
// to ensure that #get does not clear the PersistenceContext.
persistenceContext.beforeLoad();
try {
return get( entityName, id );
}
finally {
persistenceContext.afterLoad();
}
} }
private Object createProxy(EntityKey entityKey) { private Object createProxy(EntityKey entityKey) {