From 870b5b53acfca73e667d26391c774c866897c621 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 27 Feb 2019 17:13:49 +0000 Subject: [PATCH] Fix some code --- .../QueuedOperationCollectionAction.java | 24 ++++++++------- .../BagDelayedOperationNoCascadeTest.java | 30 +++++++++++++------ .../sqm/execution/EntityQuerySmokeTests.java | 4 ++- .../SessionFactoryBasedFunctionalTest.java | 4 +++ .../testing/junit5/SessionFactoryScope.java | 18 +++++++++++ 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/QueuedOperationCollectionAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/QueuedOperationCollectionAction.java index 01aa982071c4..f35856ad25ce 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/QueuedOperationCollectionAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/QueuedOperationCollectionAction.java @@ -7,7 +7,9 @@ package org.hibernate.action.internal; import org.hibernate.HibernateException; +import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.model.domain.spi.PersistentCollectionDescriptor; @@ -39,16 +41,16 @@ public QueuedOperationCollectionAction( public void execute() throws HibernateException { getPersistentCollectionDescriptor().processQueuedOps( getCollection(), getKey(), getSession() ); -// // TODO: It would be nice if this could be done safely by CollectionPersister#processQueuedOps; -// // Can't change the SPI to do this though. -// ((AbstractPersistentCollection) getCollection() ).clearOperationQueue(); -// -// // The other CollectionAction types call CollectionEntry#afterAction, which -// // clears the dirty flag. We don't want to call CollectionEntry#afterAction unless -// // there is no other CollectionAction that will be executed on the same collection. -// final CollectionEntry ce = getSession().getPersistenceContext().getCollectionEntry( getCollection() ); -// if ( !ce.isDoremove() && !ce.isDoupdate() && !ce.isDorecreate() ) { -// ce.afterAction( getCollection() ); -// } + // TODO: It would be nice if this could be done safely by CollectionPersister#processQueuedOps; + // Can't change the SPI to do this though. + ((AbstractPersistentCollection) getCollection() ).clearOperationQueue(); + + // The other CollectionAction types call CollectionEntry#afterAction, which + // clears the dirty flag. We don't want to call CollectionEntry#afterAction unless + // there is no other CollectionAction that will be executed on the same collection. + final CollectionEntry ce = getSession().getPersistenceContext().getCollectionEntry( getCollection() ); + if ( !ce.isDoremove() && !ce.isDoupdate() && !ce.isDorecreate() ) { + ce.afterAction( getCollection() ); + } } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java index 27aeed520bdd..576dbdec9f4a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java @@ -18,6 +18,7 @@ import javax.persistence.OneToMany; import org.hibernate.Hibernate; +import org.hibernate.Transaction; import org.hibernate.collection.internal.AbstractPersistentCollection; import org.hibernate.testing.TestForIssue; @@ -167,15 +168,26 @@ public void testMergeInitializedBagAndRemerge() { ); // Merge detached Parent with initialized children - Parent mergedParent = inTransaction( session -> { - Parent p = (Parent) session.merge( savedParent ); - // after merging, p#children will be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertTrue( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - return p; - - } ); - assertFalse( ( (AbstractPersistentCollection) mergedParent.getChildren() ).hasQueuedOperations() ); + Parent mergedParent = inSession( + session -> { + Transaction transaction = session.beginTransaction(); + Parent p; + try { + p = (Parent) session.merge( savedParent ); + // after merging, p#children will be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertTrue( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + transaction.commit(); + }catch (Exception e){ + if(transaction.isActive()){ + transaction.rollback(); + } + throw e; + } + assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + return p; + } + ); // Merge detached Parent, now with uninitialized children no queued operations inTransaction( diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/execution/EntityQuerySmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/execution/EntityQuerySmokeTests.java index 2d9f874ebd22..e2e1c20f70b4 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/execution/EntityQuerySmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/sqm/execution/EntityQuerySmokeTests.java @@ -164,7 +164,9 @@ public void testRootEntityManyToOneAttributeReference() { @Test public void testJoinedSubclassRoot() { inSession( - session -> session.createQuery( "select p from Payment p" ).list() + session -> { + session.createQuery( "select p from Payment p" ).list(); + } ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java index 2b607cd9c083..e82a4b75ad8b 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java @@ -200,6 +200,10 @@ protected R inTransaction(Function action) { return sessionFactoryScope().inTransaction( action ); } + protected R inSession(Function action) { + return sessionFactoryScope.inSession( action ); + } + protected void inSession(Consumer action) { sessionFactoryScope().inSession( action ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryScope.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryScope.java index ab1122014eca..198a5863434f 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryScope.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryScope.java @@ -70,6 +70,24 @@ public void inTransaction(Consumer action) { inTransaction( getSessionFactory(), action ); } + protected R inSession(Function action) { + return inSession( getSessionFactory(), action ); + } + + private R inSession(SessionFactoryImplementor sfi, Function action) { + log.trace( "##inSession(SF,action)" ); + + try (SessionImplementor session = (SessionImplementor) sfi.openSession()) { + log.trace( "Session opened, calling action" ); + R result = action.apply( session ); + log.trace( "called action" ); + return result; + } + finally { + log.trace( "Session close - auto-close lock" ); + } + } + private void inSession(SessionFactoryImplementor sfi, Consumer action) { log.trace( "##inSession(SF,action)" );