HHH-7674 DB locks not cleared on

LazyLoadingTest#testLazyCollectionLoadingWithClearedSession
This commit is contained in:
brmeyer 2012-10-10 22:01:32 -04:00
parent c9fd71fe57
commit 25a98fada3
2 changed files with 43 additions and 4 deletions

View File

@ -23,7 +23,6 @@
*/ */
package org.hibernate.collection.internal; package org.hibernate.collection.internal;
import javax.naming.NamingException;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -33,7 +32,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import org.jboss.logging.Logger; import javax.naming.NamingException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -55,6 +54,7 @@ import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.jboss.logging.Logger;
/** /**
* Base class implementing {@link org.hibernate.collection.spi.PersistentCollection} * Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
@ -175,6 +175,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) { private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) {
SessionImplementor originalSession = null; SessionImplementor originalSession = null;
boolean isTempSession = false; boolean isTempSession = false;
boolean isJTA = false;
if ( session == null ) { if ( session == null ) {
if ( specjLazyLoad ) { if ( specjLazyLoad ) {
@ -207,6 +208,22 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
} }
if ( isTempSession ) { if ( isTempSession ) {
// TODO: On the next major release, add an
// 'isJTA' or 'getTransactionFactory' method to Session.
isJTA = session.getTransactionCoordinator()
.getTransactionContext().getTransactionEnvironment()
.getTransactionFactory()
.compatibleWithJtaSynchronization();
if ( !isJTA ) {
// Explicitly handle the transactions only if we're not in
// a JTA environment. A lazy loading temporary session can
// be created even if a current session and transaction are
// open (ex: session.clear() was used). We must prevent
// multiple transactions.
( ( Session) session ).beginTransaction();
}
session.getPersistenceContext().addUninitializedDetachedCollection( session.getPersistenceContext().addUninitializedDetachedCollection(
session.getFactory().getCollectionPersister( getRole() ), session.getFactory().getCollectionPersister( getRole() ),
this this
@ -220,6 +237,9 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
if ( isTempSession ) { if ( isTempSession ) {
// make sure the just opened temp session gets closed! // make sure the just opened temp session gets closed!
try { try {
if ( !isJTA ) {
( ( Session) session ).getTransaction().commit();
}
( (Session) session ).close(); ( (Session) session ).close();
} }
catch (Exception e) { catch (Exception e) {

View File

@ -23,10 +23,9 @@
*/ */
package org.hibernate.proxy; package org.hibernate.proxy;
import javax.naming.NamingException;
import java.io.Serializable; import java.io.Serializable;
import org.jboss.logging.Logger; import javax.naming.NamingException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException; import org.hibernate.LazyInitializationException;
@ -38,6 +37,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.SessionFactoryRegistry; import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.jboss.logging.Logger;
/** /**
* Convenience base class for lazy initialization handlers. Centralizes the basic plumbing of doing lazy * Convenience base class for lazy initialization handlers. Centralizes the basic plumbing of doing lazy
@ -191,12 +191,31 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid ); SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
SessionImplementor session = (SessionImplementor) sf.openSession(); SessionImplementor session = (SessionImplementor) sf.openSession();
// TODO: On the next major release, add an
// 'isJTA' or 'getTransactionFactory' method to Session.
boolean isJTA = session.getTransactionCoordinator()
.getTransactionContext().getTransactionEnvironment()
.getTransactionFactory()
.compatibleWithJtaSynchronization();
if ( !isJTA ) {
// Explicitly handle the transactions only if we're not in
// a JTA environment. A lazy loading temporary session can
// be created even if a current session and transaction are
// open (ex: session.clear() was used). We must prevent
// multiple transactions.
( ( Session) session ).beginTransaction();
}
try { try {
target = session.immediateLoad( entityName, id ); target = session.immediateLoad( entityName, id );
} }
finally { finally {
// make sure the just opened temp session gets closed! // make sure the just opened temp session gets closed!
try { try {
if ( !isJTA ) {
( ( Session) session ).getTransaction().commit();
}
( (Session) session ).close(); ( (Session) session ).close();
} }
catch (Exception e) { catch (Exception e) {