diff --git a/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java b/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java index 65a65f95b9..1983dbee6f 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java @@ -34,8 +34,6 @@ import java.util.ListIterator; import javax.naming.NamingException; -import org.jboss.logging.Logger; - import org.hibernate.AssertionFailure; import org.hibernate.FlushMode; import org.hibernate.HibernateException; @@ -49,7 +47,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.Status; import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.SessionFactoryRegistry; import org.hibernate.internal.util.MarkerObject; import org.hibernate.internal.util.collections.EmptyIterator; @@ -59,6 +56,7 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; import org.hibernate.type.ComponentType; import org.hibernate.type.Type; +import org.jboss.logging.Logger; /** * Base class implementing {@link org.hibernate.collection.spi.PersistentCollection} @@ -66,9 +64,7 @@ import org.hibernate.type.Type; * @author Gavin King */ public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection { - private static final CoreMessageLogger LOG = Logger.getMessageLogger( - CoreMessageLogger.class, AbstractPersistentCollection.class.getName() - ); + private static final Logger log = Logger.getLogger( AbstractPersistentCollection.class ); private transient SessionImplementor session; private boolean initialized; @@ -247,7 +243,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers ( (Session) session ).close(); } catch (Exception e) { - LOG.warn( "Unable to close temporary session used to load lazy collection associated to no session" ); + log.warn( "Unable to close temporary session used to load lazy collection associated to no session" ); } session = originalSession; } @@ -606,9 +602,6 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers return true; } else { - if ( this.session != null ) { - LOG.logCannotUnsetUnexpectedSessionInCollection( generateUnexpectedSessionStateMessage( currentSession ) ); - } return false; } } @@ -637,23 +630,26 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers * @throws HibernateException if the collection was already associated * with another open session */ - @Override public final boolean setCurrentSession(SessionImplementor session) throws HibernateException { if ( session == this.session ) { return false; } else { - if ( this.session != null ) { - final String msg = generateUnexpectedSessionStateMessage( session ); - if ( isConnectedToSession() ) { + if ( isConnectedToSession() ) { + CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this ); + if ( ce == null ) { throw new HibernateException( - "Illegal attempt to associate a collection with two open sessions. " + msg + "Illegal attempt to associate a collection with two open sessions" ); } else { - LOG.logUnexpectedSessionInCollectionNotConnected( msg ); - this.session = session; - return true; + throw new HibernateException( + "Illegal attempt to associate a collection with two open sessions: " + + MessageHelper.collectionInfoString( + ce.getLoadedPersister(), this, + ce.getLoadedKey(), session + ) + ); } } else { @@ -663,50 +659,9 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers } } - private String generateUnexpectedSessionStateMessage(SessionImplementor session) { - // NOTE: If this.session != null, this.session may be operating on this collection - // (e.g., by changing this.role, this.key, or even this.session) in a different thread. - - // Grab the current role and key (it can still get changed by this.session...) - // If this collection is connected to this.session, then this.role and this.key should - // be consistent with the CollectionEntry in this.session (as long as this.session doesn't - // change it). Don't access the CollectionEntry in this.session because that could result - // in multi-threaded access to this.session. - final String roleCurrent = role; - final Serializable keyCurrent = key; - - final StringBuilder sb = new StringBuilder( "Collection : " ); - if ( roleCurrent != null ) { - sb.append( MessageHelper.collectionInfoString( roleCurrent, keyCurrent ) ); - } - else { - final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this ); - if ( ce != null ) { - sb.append( - MessageHelper.collectionInfoString( - ce.getLoadedPersister(), - this, - ce.getLoadedKey(), - session - ) - ); - } - else { - sb.append( "" ); - } - } - // only include the collection contents if debug logging - if ( LOG.isDebugEnabled() ) { - final String collectionContents = wasInitialized() ? toString() : ""; - sb.append( "\nCollection contents: [" ).append( collectionContents ).append( "]" ); - } - return sb.toString(); - } - /** * Do we need to completely recreate this collection when it changes? */ - @Override public boolean needsRecreate(CollectionPersister persister) { // Workaround for situations like HHH-7072. If the collection element is a component that consists entirely // of nullable properties, we currently have to forcefully recreate the entire collection. See the use diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java index c1586ba917..4b510873a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CoreMessageLogger.java @@ -1652,12 +1652,4 @@ public interface CoreMessageLogger extends BasicLogger { @LogMessage(level = DEBUG) @Message(value = "Creating pooled optimizer (lo) with [incrementSize=%s; returnClass=%s]", id = 467) void creatingPooledLoOptimizer(int incrementSize, String name); - - @LogMessage(level = WARN) - @Message(value = "An unexpected session is defined for a collection, but the collection is not connected to that session. A persistent collection may only be associated with one session at a time. Overwriting session. %s", id = 470) - void logUnexpectedSessionInCollectionNotConnected(String msg); - - @LogMessage(level = WARN) - @Message(value = "Cannot unset session in a collection because an unexpected session is defined. A persistent collection may only be associated with one session at a time. %s", id = 471 ) - void logCannotUnsetUnexpectedSessionInCollection(String msg); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/multisession/MultipleSessionCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/multisession/MultipleSessionCollectionTest.java deleted file mode 100644 index 5ffa0d4bdf..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/multisession/MultipleSessionCollectionTest.java +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2014, Red Hat Inc. or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Inc. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.test.collection.multisession; - -import java.util.HashSet; -import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.jboss.logging.Logger; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.collection.internal.AbstractPersistentCollection; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.spi.CollectionEntry; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -/** - * @author Gail Badner - */ -public class MultipleSessionCollectionTest extends BaseCoreFunctionalTestCase { - private static final Logger log = Logger.getLogger( MultipleSessionCollectionTest.class ); - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testSaveOrUpdateOwnerWithCollectionInNewSessionBeforeFlush() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.saveOrUpdate( p ); - - // try to save the same entity in a new session before flushing the first session - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testSaveOrUpdateOwnerWithCollectionInNewSessionAfterFlush() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.saveOrUpdate( p ); - s1.flush(); - - // try to save the same entity in a new session after flushing the first session - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testSaveOrUpdateOwnerWithUninitializedCollectionInNewSession() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( p ); - s.getTransaction().commit(); - s.close(); - - Session s1 = openSession(); - s1.getTransaction().begin(); - p = (Parent) s1.get( Parent.class, p.id ); - assertFalse( Hibernate.isInitialized( p.children ) ); - - // try to save the same entity (with an uninitialized collection) in a new session - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to initialize collection, modify and commit in first session - assertFalse( Hibernate.isInitialized( p.children ) ); - Hibernate.initialize( p.children ); - p.children.add( new Child() ); - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( 2, pGet.children.size()); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testSaveOrUpdateOwnerWithInitializedCollectionInNewSession() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( p ); - s.getTransaction().commit(); - s.close(); - - Session s1 = openSession(); - s1.getTransaction().begin(); - p = (Parent) s1.get( Parent.class, p.id ); - Hibernate.initialize( p.children ); - - // try to save the same entity (with an initialized collection) in a new session - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - // - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testCopyPersistentCollectionReferenceBeforeFlush() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.persist( p ); - - // Copy p.children into a different Parent before flush and try to save in new session. - - Parent pWithSameChildren = new Parent(); - pWithSameChildren.children = p.children; - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( pWithSameChildren ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testCopyPersistentCollectionReferenceAfterFlush() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.persist( p ); - s1.flush(); - - // Copy p.children into a different Parent after flush and try to save in new session. - - Parent pWithSameChildren = new Parent(); - pWithSameChildren.children = p.children; - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( pWithSameChildren ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testCopyUninitializedCollectionReferenceAfterGet() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( p ); - s.getTransaction().commit(); - s.close(); - - Session s1 = openSession(); - s1.getTransaction().begin(); - p = (Parent) s1.get( Parent.class, p.id ); - assertFalse( Hibernate.isInitialized( p.children ) ); - - // Copy p.children (uninitialized) into a different Parent and try to save in new session. - - Parent pWithSameChildren = new Parent(); - pWithSameChildren.children = p.children; - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( pWithSameChildren ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testCopyInitializedCollectionReferenceAfterGet() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( p ); - s.getTransaction().commit(); - s.close(); - - Session s1 = openSession(); - s1.getTransaction().begin(); - p = (Parent) s1.get( Parent.class, p.id ); - Hibernate.initialize( p.children ); - - // Copy p.children (initialized) into a different Parent.children and try to save in new session. - - Parent pWithSameChildren = new Parent(); - pWithSameChildren.children = p.children; - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( pWithSameChildren ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testCopyInitializedCollectionReferenceToNewEntityCollectionRoleAfterGet() { - Parent p = new Parent(); - Child c = new Child(); - p.children.add( c ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( p ); - s.getTransaction().commit(); - s.close(); - - Session s1 = openSession(); - s1.getTransaction().begin(); - p = (Parent) s1.get( Parent.class, p.id ); - Hibernate.initialize( p.children ); - - // Copy p.children (initialized) into a different Parent.oldChildren (note different collection role) - // and try to save in new session. - - Parent pWithSameChildren = new Parent(); - pWithSameChildren.oldChildren = p.children; - - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( pWithSameChildren ); - s2.getTransaction().commit(); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit in first session - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - Parent pGet = (Parent) s1.get( Parent.class, p.id ); - assertEquals( c.id, pGet.children.iterator().next().id ); - session.delete( pGet ); - s1.getTransaction().commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testDeleteCommitCopyToNewOwnerInNewSession() { - Parent p1 = new Parent(); - p1.nickNames.add( "nick" ); - Parent p2 = new Parent(); - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.save( p1 ); - s1.save( p2 ); - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - s1.delete( p1 ); - s1.flush(); - s1.getTransaction().commit(); - - // need to commit after flushing; otherwise, will get lock failure when try to move the collection below - - assertNull( ( (SessionImplementor) s1 ).getPersistenceContext().getEntry( p1 ) ); - CollectionEntry ceChildren = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.children ); - CollectionEntry ceNickNames = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.nickNames ); - assertNull( ceChildren ); - assertNull( ceNickNames ); - assertNull( ( ( AbstractPersistentCollection) p1.children ).getSession() ); - assertNull( ( ( AbstractPersistentCollection) p1.oldChildren ).getSession() ); - assertNull( ( ( AbstractPersistentCollection) p1.nickNames ).getSession() ); - assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() ); - - // Assign the deleted collection to a different entity with same collection role (p2.nickNames) - - p2.nickNames = p1.nickNames; - Session s2 = openSession(); - s2.getTransaction().begin(); - s2.saveOrUpdate( p2 ); - s2.getTransaction().commit(); - s2.close(); - - s1.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testDeleteCommitCopyToNewOwnerNewCollectionRoleInNewSession() { - Parent p1 = new Parent(); - p1.nickNames.add( "nick" ); - Parent p2 = new Parent(); - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.save( p1 ); - s1.save( p2 ); - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - s1.delete( p1 ); - s1.flush(); - s1.getTransaction().commit(); - - // need to commit after flushing; otherwise, will get lock failure when try to move the collection below - - assertNull( ( (SessionImplementor) s1 ).getPersistenceContext().getEntry( p1 ) ); - CollectionEntry ceChildren = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.children ); - CollectionEntry ceNickNames = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.nickNames ); - assertNull( ceChildren ); - assertNull( ceNickNames ); - assertNull( ( ( AbstractPersistentCollection) p1.children ).getSession() ); - assertNull( ( ( AbstractPersistentCollection) p1.oldChildren ).getSession() ); - assertNull( ( ( AbstractPersistentCollection) p1.nickNames ).getSession() ); - assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() ); - - // Assign the deleted collection to a different entity with different collection role (p2.oldNickNames) - - p2.oldNickNames = p1.nickNames; - Session s2 = openSession(); - s2.getTransaction().begin(); - s2.saveOrUpdate( p2 ); - s2.getTransaction().commit(); - s2.close(); - - s1.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testDeleteCopyToNewOwnerInNewSessionBeforeFlush() { - Parent p1 = new Parent(); - p1.nickNames.add( "nick" ); - Parent p2 = new Parent(); - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.save( p1 ); - s1.save( p2 ); - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - s1.delete( p1 ); - - // Assign the deleted collection to a different entity with same collection role (p2.nickNames) - // before committing delete. - - p2.nickNames = p1.nickNames; - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p2 ); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit the original delete - s1.getTransaction().commit(); - s1.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-9518" ) - public void testDeleteCopyToNewOwnerNewCollectionRoleInNewSessionBeforeFlush() { - Parent p1 = new Parent(); - p1.nickNames.add( "nick" ); - Parent p2 = new Parent(); - Session s1 = openSession(); - s1.getTransaction().begin(); - s1.save( p1 ); - s1.save( p2 ); - s1.getTransaction().commit(); - s1.close(); - - s1 = openSession(); - s1.getTransaction().begin(); - s1.delete( p1 ); - - // Assign the deleted collection to a different entity with different collection role (p2.oldNickNames) - // before committing delete. - - p2.oldNickNames = p1.nickNames; - Session s2 = openSession(); - s2.getTransaction().begin(); - try { - s2.saveOrUpdate( p2 ); - fail( "should have thrown HibernateException" ); - } - catch (HibernateException ex) { - log.error( ex ); - s2.getTransaction().rollback(); - } - finally { - s2.close(); - } - - // should still be able to commit the original delete - s1.getTransaction().commit(); - s1.close(); - } - - @Override - public Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } - - @Entity - @Table(name="Parent") - public static class Parent { - @Id - @GeneratedValue - private Long id; - - @ElementCollection - private Set nickNames = new HashSet(); - - @ElementCollection - private Set oldNickNames = new HashSet(); - - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn - private Set children = new HashSet(); - - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn - private Set oldChildren = new HashSet(); - - } - - @Entity - @Table(name="Child") - public static class Child { - @Id - @GeneratedValue - private Long id; - - } -}