From dfb3511923f008a49c9ceaa51b190b9f711d8835 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Thu, 18 Jun 2020 19:31:52 +0100 Subject: [PATCH] Re-enabled additional tests --- .../test/collection/basic/Contact.java | 2 +- .../test/collection/basic/EmailAddress.java | 2 +- .../basic/JoinFetchElementCollectionTest.java | 103 ++ .../{ => orm}/test/collection/basic/User.java | 2 +- .../BagDelayedOperationNoCascadeTest.java | 298 ++++ .../BagDelayedOperationTest.java | 392 +++++ .../DetachedBagDelayedOperationTest.java | 129 +- .../delayedOperation/ListAddTest.java | 277 ++++ .../ListDelayedOperationTest.java | 478 ++++++ .../SetDelayedOperationTest.java | 452 ++++++ .../orm/test/filter/DynamicFilterTest.java | 1361 +++++++++-------- .../basic/JoinFetchElementCollectionTest.java | 115 -- .../BagDelayedOperationNoCascadeTest.java | 288 ---- .../BagDelayedOperationTest.java | 387 ----- .../delayedOperation/ListAddTest.java | 276 ---- .../ListDelayedOperationTest.java | 465 ------ .../SetDelayedOperationTest.java | 448 ------ 17 files changed, 2763 insertions(+), 2712 deletions(-) rename hibernate-core/src/test/java/org/hibernate/{ => orm}/test/collection/basic/Contact.java (98%) rename hibernate-core/src/test/java/org/hibernate/{ => orm}/test/collection/basic/EmailAddress.java (96%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/JoinFetchElementCollectionTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm}/test/collection/basic/User.java (97%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationTest.java rename hibernate-core/src/test/java/org/hibernate/{ => orm}/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java (80%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListAddTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListDelayedOperationTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/SetDelayedOperationTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/basic/JoinFetchElementCollectionTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListAddTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListDelayedOperationTest.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/SetDelayedOperationTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/Contact.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/Contact.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/collection/basic/Contact.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/Contact.java index 988fe1fe62..c0745b08c5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/Contact.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/Contact.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.collection.basic; +package org.hibernate.orm.test.collection.basic; import java.io.Serializable; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/EmailAddress.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/EmailAddress.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/collection/basic/EmailAddress.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/EmailAddress.java index a964df28de..f38f0b4625 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/EmailAddress.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/EmailAddress.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.collection.basic; +package org.hibernate.orm.test.collection.basic; import java.io.Serializable; import javax.persistence.*; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/JoinFetchElementCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/JoinFetchElementCollectionTest.java new file mode 100644 index 0000000000..89397b78ab --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/JoinFetchElementCollectionTest.java @@ -0,0 +1,103 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.collection.basic; + +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.FailureExpected; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@DomainModel( + annotatedClasses = { + Contact.class, EmailAddress.class, User.class + } +) +@SessionFactory +public class JoinFetchElementCollectionTest { + + @Test + @TestForIssue(jiraKey = "HHH-8206") + @FailureExpected(jiraKey = "HHH-8206", reason = "This is not explicitly supported, however should arguably throw an exception") + public void testJoinFetchesByPath(SessionFactoryScope scope) { + Set emailAddresses = new HashSet(); + emailAddresses.add( new EmailAddress( "test1@test.com" ) ); + emailAddresses.add( new EmailAddress( "test2@test.com" ) ); + emailAddresses.add( new EmailAddress( "test3@test.com" ) ); + + // Session 1: Insert a user with email addresses but no emailAddresses2 + scope.inTransaction( + session -> { + User user = new User(); + user.setName( "john" ); + Contact contact = new Contact(); + contact.setName( "John Doe" ); + contact.setEmailAddresses( emailAddresses ); + contact = (Contact) session.merge( contact ); + user.setContact( contact ); + user = (User) session.merge( user ); + } + ); + // Session 2: Retrieve the user object and check if the sets have the expected values + scope.inTransaction( + session -> { + final String qry = "SELECT user " + + "FROM User user " + + "LEFT OUTER JOIN FETCH user.contact " + + "LEFT OUTER JOIN FETCH user.contact.emailAddresses2 " + + "LEFT OUTER JOIN FETCH user.contact.emailAddresses"; + User user = (User) session.createQuery( qry ).uniqueResult(); + assertEquals( emailAddresses, user.getContact().getEmailAddresses() ); + assertTrue( user.getContact().getEmailAddresses2().isEmpty() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5465") + public void testJoinFetchElementCollection(SessionFactoryScope scope) { + Set emailAddresses = new HashSet(); + emailAddresses.add( new EmailAddress( "test1@test.com" ) ); + emailAddresses.add( new EmailAddress( "test2@test.com" ) ); + emailAddresses.add( new EmailAddress( "test3@test.com" ) ); + + // Session 1: Insert a user with email addresses but no emailAddresses2 + scope.inTransaction( + session -> { + User user = new User(); + user.setName( "john" ); + Contact contact = new Contact(); + contact.setName( "John Doe" ); + contact.setEmailAddresses( emailAddresses ); + contact = (Contact) session.merge( contact ); + user.setContact( contact ); + user = (User) session.merge( user ); + } + ); + // Session 2: Retrieve the user object and check if the sets have the expected values + scope.inTransaction( + session -> { + final String qry = "SELECT user " + + "FROM User user " + + "LEFT OUTER JOIN FETCH user.contact c " + + "LEFT OUTER JOIN FETCH c.emailAddresses2 " + + "LEFT OUTER JOIN FETCH c.emailAddresses"; + User user = (User) session.createQuery( qry ).uniqueResult(); + assertEquals( emailAddresses, user.getContact().getEmailAddresses() ); + assertTrue( user.getContact().getEmailAddresses2().isEmpty() ); + } + ); + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/User.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/User.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/collection/basic/User.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/User.java index d76faba9d4..bba2c86de5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/User.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/basic/User.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.collection.basic; +package org.hibernate.orm.test.collection.basic; import java.io.Serializable; import javax.persistence.Basic; 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 new file mode 100644 index 0000000000..fec6b8a0f7 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java @@ -0,0 +1,298 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.collection.delayedOperation; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.Hibernate; +import org.hibernate.collection.internal.AbstractPersistentCollection; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hibernate.orm.test.collection.delayedOperation.BagDelayedOperationNoCascadeTest.Child; +import static org.hibernate.orm.test.collection.delayedOperation.BagDelayedOperationNoCascadeTest.Parent; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests delayed operations that are queued for a PersistentBag. The Bag does not have + * to be extra-lazy to queue the operations. + * + * @author Gail Badner + */ +@DomainModel( + annotatedClasses = { + Parent.class, + Child.class + } +) +@SessionFactory +public class BagDelayedOperationNoCascadeTest { + private Long parentId; + + @BeforeEach + public void setup(SessionFactoryScope scope) { + // start by cleaning up in case a test fails + if ( parentId != null ) { + cleanup( scope ); + } + + Parent parent = new Parent(); + Child child1 = new Child( "Sherman" ); + Child child2 = new Child( "Yogi" ); + parent.addChild( child1 ); + parent.addChild( child2 ); + + scope.inTransaction( + session -> { + session.persist( child1 ); + session.persist( child2 ); + session.persist( parent ); + } + ); + + parentId = parent.getId(); + } + + @AfterEach + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createQuery( "delete from Child" ).executeUpdate(); + session.createQuery( "delete from Parent" ).executeUpdate(); + } + ); + + parentId = null; + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddManaged(SessionFactoryScope scope) { + // Add 2 Child entities + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Add a managed Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the first Child so it is managed; add to collection + p.addChild( session.get( Child.class, c1.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add the other managed Child, merge and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the second Child so it is managed; add to collection + p.addChild( session.get( Child.class, c2.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-11209") + public void testMergeInitializedBagAndRemerge(SessionFactoryScope scope) { + Parent parent = scope.fromTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // initialize + Hibernate.initialize( p.getChildren() ); + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + return p; + } + ); + + Parent modifiedParent = scope.fromTransaction( + session -> { + Parent p = (Parent) session.merge( parent ); + Child c = new Child( "Zeke" ); + c.setParent( p ); + session.persist( c ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p.getChildren().size(); + p.getChildren().add( c ); + return p; + } + ); + + + // Merge detached Parent with initialized children + Parent p = scope.fromTransaction( + session -> { + Parent mergedParent = (Parent) session.merge( modifiedParent ); + // after merging, p#children will be uninitialized + assertFalse( Hibernate.isInitialized( mergedParent.getChildren() ) ); + assertTrue( ( (AbstractPersistentCollection) mergedParent.getChildren() ).hasQueuedOperations() ); + return mergedParent; + } + ); + + assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + + // Merge detached Parent, now with uninitialized children no queued operations + scope.inTransaction( + session -> { + Parent mergedParent = (Parent) session.merge( p ); + assertFalse( Hibernate.isInitialized( mergedParent.getChildren() ) ); + assertFalse( ( (AbstractPersistentCollection) mergedParent.getChildren() ).hasQueuedOperations() ); + + } + ); + } + + @Entity(name = "Parent") + public static class Parent { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + // Don't need extra-lazy to delay add operations to a bag. + @OneToMany(mappedBy = "parent") + private List children = new ArrayList<>(); + + public Parent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void addChild(Child child) { + children.add( child ); + child.setParent( this ); + } + } + + @Entity(name = "Child") + public static class Child { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String name; + + @ManyToOne + private Parent parent; + + public Child() { + } + + public Child(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } + + @Override + public String toString() { + return "Child{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + Child child = (Child) o; + + return name.equals( child.name ); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationTest.java new file mode 100644 index 0000000000..20f1e1f1c9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/BagDelayedOperationTest.java @@ -0,0 +1,392 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.collection.delayedOperation; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.Hibernate; +import org.hibernate.collection.internal.AbstractPersistentCollection; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/** + * Tests delayed operations that are queued for a PersistentBag. The Bag does not have + * to be extra-lazy to queue the operations. + * + * @author Gail Badner + */ +@DomainModel( + annotatedClasses = { + BagDelayedOperationTest.Parent.class, + BagDelayedOperationTest.Child.class + } +) +@SessionFactory +public class BagDelayedOperationTest { + private Long parentId; + + @BeforeEach + public void setup(SessionFactoryScope scope) { + // start by cleaning up in case a test fails + if ( parentId != null ) { + cleanup( scope ); + } + + Parent parent = new Parent(); + Child child1 = new Child( "Sherman" ); + Child child2 = new Child( "Yogi" ); + parent.addChild( child1 ); + parent.addChild( child2 ); + + scope.inTransaction( + session -> + session.persist( parent ) + ); + + parentId = parent.getId(); + } + + @AfterEach + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Parent parent = session.get( Parent.class, parentId ); + parent.getChildren().clear(); + session.delete( parent ); + } + ); + + parentId = null; + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddDetached(SessionFactoryScope scope) { + // Create 2 detached Child objects. + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Now Child c is detached. + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add detached Child c + p.addChild( c1 ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + // Add a detached Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add another detached Child, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p.addChild( c2 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddTransient(SessionFactoryScope scope) { + // Add a transient Child and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Darwin" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add another transient Child and commit again. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Comet" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddManaged(SessionFactoryScope scope) { + // Add 2 Child entities + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Add a managed Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the first Child so it is managed; add to collection + p.addChild( session.get( Child.class, c1.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add the other managed Child, merge and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the second Child so it is managed; add to collection + p.addChild( session.get( Child.class, c2.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-11209") + public void testMergeInitializedBagAndRemerge(SessionFactoryScope scope) { + Parent parent = scope.fromTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // initialize + Hibernate.initialize( p.getChildren() ); + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + return p; + } + ); + + Parent modifiedParent = scope.fromTransaction( + session -> { + Parent p = (Parent) session.merge( parent ); + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + Child c = new Child( "Zeke" ); + c.setParent( p ); + session.persist( c ); + p.getChildren().size(); + p.getChildren().add( c ); + return p; + } + ); + + // Merge detached Parent with initialized children + Parent mergedParent = scope.fromTransaction( + session -> { + Parent p = (Parent) session.merge( modifiedParent ); + // after merging, p#children will be initialized + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + return p; + } + ); + + // Merge detached Parent + scope.inTransaction( + session -> { + Parent p = (Parent) session.merge( mergedParent ); + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + + } + ); + } + + @Entity(name = "Parent") + public static class Parent { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + // Don't need extra-lazy to delay add operations to a bag. + @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) + private List children = new ArrayList<>(); + + public Parent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void addChild(Child child) { + children.add( child ); + child.setParent( this ); + } + } + + @Entity(name = "Child") + public static class Child { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String name; + + @ManyToOne + private Parent parent; + + public Child() { + } + + public Child(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } + + @Override + public String toString() { + return "Child{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + Child child = (Child) o; + + return name.equals( child.name ); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java similarity index 80% rename from hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java index e6b2fd95e2..d89675b076 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java @@ -5,7 +5,7 @@ * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.collection.delayedOperation; +package org.hibernate.orm.test.collection.delayedOperation; import java.util.ArrayList; import java.util.Arrays; @@ -28,36 +28,36 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.CollectionType; import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.logger.LoggerInspectionRule; import org.hibernate.testing.logger.Triggerable; -import org.junit.After; -import org.junit.Before; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jboss.logging.Logger; -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * Tests merge of detached PersistentBag * * @author Gail Badner */ -public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } +@DomainModel( + annotatedClasses = { + DetachedBagDelayedOperationTest.Parent.class, + DetachedBagDelayedOperationTest.Child.class + } +) +@SessionFactory +public class DetachedBagDelayedOperationTest { @Rule public LoggerInspectionRule logInspectionCollectionType = new LoggerInspectionRule( @@ -74,8 +74,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase private Triggerable triggerableQueuedOperationWhenDetachFromSession; private Triggerable triggerableQueuedOperationOnRollback; - @Before - public void setup() { + @BeforeEach + public void setup(SessionFactoryScope scope) { Parent parent = new Parent(); parent.id = 1L; Child child1 = new Child( "Sherman" ); @@ -83,8 +83,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase parent.addChild( child1 ); parent.addChild( child2 ); - doInHibernate( - this::sessionFactory, session -> { + scope.inTransaction( + session -> { session.persist( child1 ); session.persist( child2 ); @@ -93,17 +93,20 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase ); triggerableIgnoreQueuedOperationsOnMerge = logInspectionCollectionType.watchForLogMessages( "HHH000494" ); - triggerableQueuedOperationWhenAttachToSession = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000495" ); - triggerableQueuedOperationWhenDetachFromSession = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000496" ); - triggerableQueuedOperationOnRollback = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000498" ); + triggerableQueuedOperationWhenAttachToSession = logInspectionAbstractPersistentCollection.watchForLogMessages( + "HHH000495" ); + triggerableQueuedOperationWhenDetachFromSession = logInspectionAbstractPersistentCollection.watchForLogMessages( + "HHH000496" ); + triggerableQueuedOperationOnRollback = logInspectionAbstractPersistentCollection.watchForLogMessages( + "HHH000498" ); resetTriggerables(); } - @After - public void cleanup() { - doInHibernate( - this::sessionFactory, session -> { + @AfterEach + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + session -> { session.createQuery( "delete from Child" ).executeUpdate(); session.createQuery( "delete from Parent" ).executeUpdate(); } @@ -111,10 +114,10 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase } @Test - @TestForIssue( jiraKey = "HHH-11209" ) - public void testMergeDetachedCollectionWithQueuedOperations() { - final Parent pOriginal = doInHibernate( - this::sessionFactory, session -> { + @TestForIssue(jiraKey = "HHH-11209") + public void testMergeDetachedCollectionWithQueuedOperations(SessionFactoryScope scope) { + final Parent pOriginal = scope.fromTransaction( + session -> { Parent p = session.get( Parent.class, 1L ); assertFalse( Hibernate.isInitialized( p.getChildren() ) ); // initialize @@ -123,8 +126,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase return p; } ); - final Parent pWithQueuedOperations = doInHibernate( - this::sessionFactory, session -> { + final Parent pWithQueuedOperations = scope.fromTransaction( + session -> { Parent p = (Parent) session.merge( pOriginal ); Child c = new Child( "Zeke" ); c.setParent( p ); @@ -138,7 +141,7 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase session.detach( p ); assertTrue( triggerableQueuedOperationWhenDetachFromSession.wasTriggered() ); assertEquals( - "HHH000496: Detaching an uninitialized collection with queued operations from a session: [org.hibernate.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", + "HHH000496: Detaching an uninitialized collection with queued operations from a session: [org.hibernate.orm.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", triggerableQueuedOperationWhenDetachFromSession.triggerMessage() ); triggerableQueuedOperationWhenDetachFromSession.reset(); @@ -155,8 +158,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase assertTrue( ( (AbstractPersistentCollection) pWithQueuedOperations.getChildren() ).hasQueuedOperations() ); // Merge detached Parent with uninitialized collection with queued operations - doInHibernate( - this::sessionFactory, session -> { + scope.inTransaction( + session -> { checkTriggerablesNotTriggered(); @@ -164,7 +167,7 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase Parent p = (Parent) session.merge( pWithQueuedOperations ); assertTrue( triggerableIgnoreQueuedOperationsOnMerge.wasTriggered() ); assertEquals( - "HHH000494: Attempt to merge an uninitialized collection with queued operations; queued operations will be ignored: [org.hibernate.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", + "HHH000494: Attempt to merge an uninitialized collection with queued operations; queued operations will be ignored: [org.hibernate.orm.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", triggerableIgnoreQueuedOperationsOnMerge.triggerMessage() ); triggerableIgnoreQueuedOperationsOnMerge.reset(); @@ -176,8 +179,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase // because that Child was flushed without a parent before being detached // along with its parent. Hibernate.initialize( p.getChildren() ); - final Set childNames = new HashSet( - Arrays.asList( new String[] { "Yogi", "Sherman" } ) + final Set childNames = new HashSet<>( + Arrays.asList( "Yogi", "Sherman" ) ); assertEquals( childNames.size(), p.getChildren().size() ); for ( Child child : p.getChildren() ) { @@ -191,10 +194,10 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase } @Test - @TestForIssue( jiraKey = "HHH-11209" ) - public void testSaveOrUpdateDetachedCollectionWithQueuedOperations() { - final Parent pOriginal = doInHibernate( - this::sessionFactory, session -> { + @TestForIssue(jiraKey = "HHH-11209") + public void testSaveOrUpdateDetachedCollectionWithQueuedOperations(SessionFactoryScope scope) { + final Parent pOriginal = scope.fromTransaction( + session -> { Parent p = session.get( Parent.class, 1L ); assertFalse( Hibernate.isInitialized( p.getChildren() ) ); // initialize @@ -203,8 +206,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase return p; } ); - final Parent pAfterDetachWithQueuedOperations = doInHibernate( - this::sessionFactory, session -> { + final Parent pAfterDetachWithQueuedOperations = scope.fromTransaction( + session -> { Parent p = (Parent) session.merge( pOriginal ); Child c = new Child( "Zeke" ); c.setParent( p ); @@ -218,7 +221,7 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase session.detach( p ); assertTrue( triggerableQueuedOperationWhenDetachFromSession.wasTriggered() ); assertEquals( - "HHH000496: Detaching an uninitialized collection with queued operations from a session: [org.hibernate.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", + "HHH000496: Detaching an uninitialized collection with queued operations from a session: [org.hibernate.orm.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", triggerableQueuedOperationWhenDetachFromSession.triggerMessage() ); triggerableQueuedOperationWhenDetachFromSession.reset(); @@ -235,8 +238,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase assertTrue( ( (AbstractPersistentCollection) pAfterDetachWithQueuedOperations.getChildren() ).hasQueuedOperations() ); // Save detached Parent with uninitialized collection with queued operations - doInHibernate( - this::sessionFactory, session -> { + scope.inTransaction( + session -> { checkTriggerablesNotTriggered(); @@ -244,7 +247,7 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase session.saveOrUpdate( pAfterDetachWithQueuedOperations ); assertTrue( triggerableQueuedOperationWhenAttachToSession.wasTriggered() ); assertEquals( - "HHH000495: Attaching an uninitialized collection with queued operations to a session: [org.hibernate.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", + "HHH000495: Attaching an uninitialized collection with queued operations to a session: [org.hibernate.orm.test.collection.delayedOperation.DetachedBagDelayedOperationTest$Parent.children#1]", triggerableQueuedOperationWhenAttachToSession.triggerMessage() ); triggerableQueuedOperationWhenAttachToSession.reset(); @@ -259,8 +262,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase // After initialization, the collection will contain the Child that was added as a // queued operation before being detached above. Hibernate.initialize( pAfterDetachWithQueuedOperations.getChildren() ); - final Set childNames = new HashSet( - Arrays.asList( new String[] { "Yogi", "Sherman", "Zeke" } ) + final Set childNames = new HashSet<>( + Arrays.asList( "Yogi", "Sherman", "Zeke" ) ); assertEquals( childNames.size(), pAfterDetachWithQueuedOperations.getChildren().size() ); for ( Child child : pAfterDetachWithQueuedOperations.getChildren() ) { @@ -274,10 +277,10 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase } @Test - @TestForIssue( jiraKey = "HHH-11209" ) - public void testCollectionWithQueuedOperationsOnRollback() { - final Parent pOriginal = doInHibernate( - this::sessionFactory, session -> { + @TestForIssue(jiraKey = "HHH-11209") + public void testCollectionWithQueuedOperationsOnRollback(SessionFactoryScope scope) { + final Parent pOriginal = scope.fromTransaction( + session -> { Parent p = session.get( Parent.class, 1L ); assertFalse( Hibernate.isInitialized( p.getChildren() ) ); // initialize @@ -287,8 +290,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase } ); try { - doInHibernate( - this::sessionFactory, session -> { + scope.inTransaction( + session -> { Parent p = (Parent) session.merge( pOriginal ); Child c = new Child( "Zeke" ); c.setParent( p ); @@ -338,7 +341,7 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase // Don't need extra-lazy to delay add operations to a bag. @OneToMany(mappedBy = "parent", cascade = CascadeType.DETACH) - private List children ; + private List children; public Parent() { } @@ -359,8 +362,8 @@ public class DetachedBagDelayedOperationTest extends BaseCoreFunctionalTestCase if ( children == null ) { children = new ArrayList<>(); } - children.add(child); - child.setParent(this); + children.add( child ); + child.setParent( this ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListAddTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListAddTest.java new file mode 100644 index 0000000000..79dcb6b301 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListAddTest.java @@ -0,0 +1,277 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.collection.delayedOperation; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; +import javax.persistence.Table; + +import org.hibernate.Hibernate; +import org.hibernate.LazyInitializationException; +import org.hibernate.collection.spi.PersistentCollection; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * @author Steve Ebersole + */ +@DomainModel( + annotatedClasses = { + ListAddTest.Quizz.class, ListAddTest.Question.class + } +) +@SessionFactory +public class ListAddTest { + + @BeforeEach + public void before(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Quizz quizz = new Quizz( 1 ); + session.persist( quizz ); + quizz.addQuestion( new Question( 1, "question 1" ) ); + quizz.addQuestion( new Question( 2, "question 2" ) ); + quizz.addQuestion( new Question( 3, "question 3" ) ); + } + ); + + } + + @AfterEach + public void after(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createQuery( "delete Question" ).executeUpdate(); + session.createQuery( "delete Quizz" ).executeUpdate(); + } + ); + } + + /** + * This test fails, but shouldn't + */ + @Test + public void addQuestionWithIndexShouldAddQuestionAtSpecifiedIndex(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Quizz quizz = session.get( Quizz.class, 1 ); + quizz.addQuestion( 1, new Question( 4, "question that should be at index 1" ) ); + + } + ); + + scope.inTransaction( + session -> { + Quizz quizz = session.get( Quizz.class, 1 ); + assertEquals( 4, quizz.getQuestions().size() ); + assertEquals( 4, quizz.getQuestions().get( 1 ).getId().longValue() ); + + } + ); + } + + @Test + public void addQuestionToDetachedQuizz(SessionFactoryScope scope) { + Quizz quizz = scope.fromTransaction( + session -> + session.get( Quizz.class, 1 ) + ); + + + assertFalse( ( (PersistentCollection) quizz.getQuestions() ).wasInitialized() ); + + try { + // this is the crux of the comment on HHH-9195 in regard to uninitialized, detached collections and + // not allowing additions + quizz.addQuestion( new Question( 4, "question 4" ) ); + + // indexed-addition should fail + quizz.addQuestion( 1, new Question( 5, "question that should be at index 1" ) ); + fail( "Expecting a failure" ); + } + catch (LazyInitializationException ignore) { + // expected + } + +// session = openSession(); +// session.beginTransaction(); +// session.merge( quizz ); +// session.getTransaction().commit(); +// session.close(); +// +// session = openSession(); +// session.getTransaction().begin(); +// quizz = session.get( Quizz.class, 1); +// assertEquals( 5, quizz.getQuestions().size() ); +// assertEquals( 5, quizz.getQuestions().get( 1 ).getId().longValue() ); +// session.getTransaction().commit(); +// session.close(); + } + + /** + * This test succeeds thanks to a dirty workaround consisting in initializing the ordered question list after the + * question has been inserted + */ + @Test + public void addQuestionWithIndexAndInitializeTheListShouldAddQuestionAtSpecifiedIndex(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Quizz quizz = session.get( Quizz.class, 1 ); + quizz.addQuestionAndInitializeLazyList( + 1, + new Question( 4, "question that should be at index 1" ) + ); + } + ); + + + scope.inTransaction( + session -> { + Quizz quizz = session.get( Quizz.class, 1 ); + + assertEquals( 4, quizz.getQuestions().size() ); + assertEquals( 4, quizz.getQuestions().get( 1 ).getId().longValue() ); + + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-10375") + public void testAddQuestionAfterSessionIsClosed(SessionFactoryScope scope) { + Quizz quizz = scope.fromTransaction( + session -> { + Quizz q = session.get( Quizz.class, 1 ); + assertThat( "expected 3 questions", q.getQuestions().size(), is( 3 ) ); + return q; + } + ); + + quizz.addQuestion( new Question( 4, "question 4" ) ); + assertThat( "expected 4 questions", quizz.getQuestions().size(), is( 4 ) ); + + quizz.addQuestion( 1, new Question( 5, "question 5" ) ); + assertThat( "expected 5 questions", quizz.getQuestions().size(), is( 5 ) ); + } + + + @Entity(name = "Question") + @Table(name = "Question") + public static class Question { + @Id + private Integer id; + private String text; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + private Quizz quizz; + + public Question() { + } + + public Question(Integer id, String text) { + this.id = id; + this.text = text; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Quizz getQuizz() { + return quizz; + } + + public void setQuizz(Quizz quizz) { + this.quizz = quizz; + } + + @Override + public String toString() { + return "Question{" + + "id=" + id + + ", text='" + text + '\'' + + '}'; + } + } + + @Entity(name = "Quizz") + @Table(name = "Quiz") + public static class Quizz { + @Id + private Integer id; + + @OneToMany(mappedBy = "quizz", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderColumn(name = "position") + private List questions = new ArrayList<>(); + + public Quizz() { + } + + public Quizz(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public List getQuestions() { + return questions; + } + + public void addQuestion(Question question) { + question.setQuizz( this ); + questions.add( question ); + } + + public void addQuestion(int index, Question question) { + question.setQuizz( this ); + questions.add( index, question ); + } + + public void addQuestionAndInitializeLazyList(int index, Question question) { + question.setQuizz( this ); + questions.add( index, question ); + Hibernate.initialize( questions ); + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListDelayedOperationTest.java new file mode 100644 index 0000000000..811f4403a7 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/ListDelayedOperationTest.java @@ -0,0 +1,478 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.collection.delayedOperation; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; + +import org.hibernate.Hibernate; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/** + * Tests delayed operations that are queued for a PersistentSet. remove( Object ) + * requires extra lazy to queue the operations. + * + * @author Gail Badner + */ +@DomainModel( + annotatedClasses = { + ListDelayedOperationTest.Parent.class, + ListDelayedOperationTest.Child.class + } +) +@SessionFactory +public class ListDelayedOperationTest { + private Long parentId; + private Long childId1; + private Long childId2; + + + @BeforeEach + public void setup(SessionFactoryScope scope) { + // start by cleaning up in case a test fails + if ( parentId != null ) { + cleanup(scope); + } + + Parent parent = new Parent(); + Child child1 = new Child( "Sherman" ); + Child child2 = new Child( "Yogi" ); + parent.addChild( child1 ); + parent.addChild( child2 ); + + scope.inTransaction( + session -> + session.persist( parent ) + ); + + parentId = parent.getId(); + childId1 = child1.getId(); + childId2 = child2.getId(); + } + + @AfterEach + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Parent parent = session.get( Parent.class, parentId ); + parent.getChildren().clear(); + session.delete( parent ); + } + ); + + parentId = null; + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddDetached(SessionFactoryScope scope) { + // Create 2 detached Child objects. + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Now Child c is detached. + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add detached Child c + p.addChild( c1 ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + + } + ); + + // Add a detached Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + + // Add another detached Child, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p.addChild( c2 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddTransient(SessionFactoryScope scope) { + // Add a transient Child and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Darwin" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + + // Add another transient Child and commit again. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Comet" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddManaged(SessionFactoryScope scope) { + // Add 2 Child entities + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Add a managed Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the first Child so it is managed; add to collection + p.addChild( session.get( Child.class, c1.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add the other managed Child, merge and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the second Child so it is managed; add to collection + p.addChild( session.get( Child.class, c2.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleRemoveDetached(SessionFactoryScope scope) { + // Get the 2 Child entities and detach. + Child c1 = scope.fromTransaction( + session -> + session.get( Child.class, childId1 ) + ); + + Child c2 = scope.fromTransaction( + session -> + session.get( Child.class, childId2 ) + ); + + + // Remove a detached entity element and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // remove a detached element and commit + Hibernate.initialize( p.getChildren() ); + p.removeChild( c1 ); + for ( Child c : p.getChildren() ) { + if ( c.equals( c1 ) ) { + session.evict( c ); + } + } + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + //s.merge( p ); + } + ); + + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + Hibernate.initialize( p.getChildren() ); + assertEquals( 1, p.getChildren().size() ); + } + ); + + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // remove a detached element and commit + p.removeChild( c2 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p = (Parent) session.merge( p ); + Hibernate.initialize( p ); + } + ); + + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 0, p.getChildren().size() ); + } + ); + } + +/* STILL WORKING ON THIS ONE... + @Test + @TestForIssue( jiraKey = "HHH-5855") + public void testSimpleRemoveManaged() { + // Remove a managed entity element and commit + Session s = openSession(); + s.getTransaction().begin(); + Parent p = s.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get c1 so it is managed, then remove and commit + p.removeChild( s.get( Child.class, childId1 ) ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.getTransaction().begin(); + p = s.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 1, p.getChildren().size() ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.getTransaction().begin(); + p = s.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get c1 so it is managed, then remove, merge and commit + p.removeChild( s.get( Child.class, childId2 ) ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + s.merge( p ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.getTransaction().begin(); + p = s.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 0, p.getChildren().size() ); + s.getTransaction().commit(); + s.close(); + } +*/ + + @Entity(name = "Parent") + public static class Parent { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) + @LazyCollection(LazyCollectionOption.EXTRA) + @OrderColumn + private List children = new ArrayList<>(); + + public Parent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void addChild(Child child) { + children.add( child ); + child.setParent( this ); + } + + public void addChild(Child child, int i) { + children.add( i, child ); + child.setParent( this ); + } + + public void removeChild(Child child) { + children.remove( child ); + child.setParent( null ); + } + } + + @Entity(name = "Child") + public static class Child { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String name; + + @ManyToOne + private Parent parent; + + public Child() { + } + + public Child(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } + + @Override + public String toString() { + return "Child{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + Child child = (Child) o; + + return name.equals( child.name ); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/SetDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/SetDelayedOperationTest.java new file mode 100644 index 0000000000..29ddf9652c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/delayedOperation/SetDelayedOperationTest.java @@ -0,0 +1,452 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.collection.delayedOperation; + +import java.util.HashSet; +import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.Hibernate; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + + +/** + * Tests delayed operations that are queued for a PersistentSet. The Set must be + * extra lazy to queue the operations. + * + * @author Gail Badner + */ +@DomainModel( + annotatedClasses = { + SetDelayedOperationTest.Parent.class, + SetDelayedOperationTest.Child.class + } +) +@SessionFactory +public class SetDelayedOperationTest { + private Long parentId; + private Long childId1; + private Long childId2; + + @BeforeEach + public void setup(SessionFactoryScope scope) { + // start by cleaning up in case a test fails + if ( parentId != null ) { + cleanup( scope ); + } + + Parent parent = new Parent(); + Child child1 = new Child( "Sherman" ); + Child child2 = new Child( "Yogi" ); + parent.addChild( child1 ); + parent.addChild( child2 ); + + scope.inTransaction( + session -> session.persist( parent ) + ); + + parentId = parent.getId(); + childId1 = child1.getId(); + childId2 = child2.getId(); + } + + @AfterEach + public void cleanup(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Parent parent = session.get( Parent.class, parentId ); + parent.getChildren().clear(); + session.delete( parent ); + } + ); + + parentId = null; + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddDetached(SessionFactoryScope scope) { + // Create 2 detached Child objects. + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Now Child c is detached. + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add detached Child c + p.addChild( c1 ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + // Add a detached Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + // Add another detached Child, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p.addChild( c2 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddTransient(SessionFactoryScope scope) { + // Add a transient Child and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Darwin" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + + } + ); + + // Add another transient Child and commit again. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // add transient Child + p.addChild( new Child( "Comet" ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleAddManaged(SessionFactoryScope scope) { + // Add 2 Child entities + Child c1 = new Child( "Darwin" ); + Child c2 = new Child( "Comet" ); + scope.inTransaction( + session -> { + session.persist( c1 ); + session.persist( c2 ); + } + ); + + // Add a managed Child and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the first Child so it is managed; add to collection + p.addChild( session.get( Child.class, c1.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 3, p.getChildren().size() ); + } + ); + + + // Add the other managed Child, merge and commit. + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get the second Child so it is managed; add to collection + p.addChild( session.get( Child.class, c2.getId() ) ); + // collection should still be uninitialized + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 4, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleRemoveDetached(SessionFactoryScope scope) { + // Get the 2 Child entities and detach. + Child c1 = scope.fromTransaction( + session -> session.get( Child.class, childId1 ) + ); + + Child c2 = scope.fromTransaction( + session -> session.get( Child.class, childId2 ) + ); + + // Remove a detached entity element and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // remove a detached element and commit + p.removeChild( c1 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 1, p.getChildren().size() ); + } + ); + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // remove a detached element and commit + p.removeChild( c2 ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p = (Parent) session.merge( p ); + Hibernate.initialize( p ); + } + ); + + // Remove a detached entity element, merge, and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 0, p.getChildren().size() ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-5855") + public void testSimpleRemoveManaged(SessionFactoryScope scope) { + // Remove a managed entity element and commit + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get c1 so it is managed, then remove and commit + p.removeChild( session.get( Child.class, childId1 ) ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 1, p.getChildren().size() ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // get c1 so it is managed, then remove, merge and commit + p.removeChild( session.get( Child.class, childId2 ) ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + session.merge( p ); + } + ); + + scope.inTransaction( + session -> { + Parent p = session.get( Parent.class, parentId ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertEquals( 0, p.getChildren().size() ); + } + ); + } + + @Entity(name = "Parent") + public static class Parent { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) + @LazyCollection(value = LazyCollectionOption.EXTRA) + private Set children = new HashSet<>(); + + public Parent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getChildren() { + return children; + } + + public void addChild(Child child) { + children.add( child ); + child.setParent( this ); + } + + public void removeChild(Child child) { + children.remove( child ); + child.setParent( null ); + } + } + + @Entity(name = "Child") + public static class Child { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String name; + + @ManyToOne + private Parent parent; + + public Child() { + } + + public Child(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } + + @Override + public String toString() { + return "Child{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + Child child = (Child) o; + + return name.equals( child.name ); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/filter/DynamicFilterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/filter/DynamicFilterTest.java index 19b00ab4ff..ef4e52ad9b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/filter/DynamicFilterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/filter/DynamicFilterTest.java @@ -22,13 +22,11 @@ import javax.persistence.criteria.Subquery; import org.hibernate.Hibernate; import org.hibernate.Session; -import org.hibernate.Transaction; import org.hibernate.cache.spi.access.CollectionDataAccess; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.IngresDialect; import org.hibernate.dialect.SybaseASE15Dialect; -import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.query.Query; import org.hibernate.transform.DistinctRootEntityResultTransformer; @@ -37,6 +35,8 @@ import org.hibernate.testing.FailureExpected; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -50,22 +50,35 @@ import static org.junit.Assert.assertTrue; * * @author Steve Ebersole */ -@SkipForDialect( value = SybaseASE15Dialect.class, jiraKey = "HHH-3637") +@SkipForDialect(value = SybaseASE15Dialect.class, jiraKey = "HHH-3637") public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { @Override public String[] getMappings() { - return new String[]{ - "filter/defs.hbm.xml", - "filter/LineItem.hbm.xml", - "filter/Order.hbm.xml", - "filter/Product.hbm.xml", - "filter/Salesperson.hbm.xml", - "filter/Department.hbm.xml", - "filter/Category.hbm.xml" + return new String[] { + "filter/defs.hbm.xml", + "filter/LineItem.hbm.xml", + "filter/Order.hbm.xml", + "filter/Product.hbm.xml", + "filter/Salesperson.hbm.xml", + "filter/Department.hbm.xml", + "filter/Category.hbm.xml" }; } + private TestData testData; + + @Before + public void setTestData() { + testData = new TestData(); + testData.prepare(); + } + + @After + public void releaseTestData() { + testData.release(); + } + @Override protected String getBaseForMappings() { return "org/hibernate/orm/test/"; @@ -84,7 +97,7 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { } @Test - @SkipForDialect( value = {SybaseASE15Dialect.class, IngresDialect.class}) + @SkipForDialect(value = { SybaseASE15Dialect.class, IngresDialect.class }) public void testSqlSyntaxOfFiltersWithUnions() { Session session = openSession(); session.enableFilter( "unioned" ); @@ -93,134 +106,150 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testSecondLevelCachedCollectionsFiltering() { - TestData testData = new TestData(); - testData.prepare(); - Session session = openSession(); - long ts = ( ( SessionImplementor ) session ).getTimestamp(); - - // Force a collection into the second level cache, with its non-filtered elements - Salesperson sp = session.load( Salesperson.class, testData.steveId ); - Hibernate.initialize( sp.getOrders() ); CollectionPersister persister = sessionFactory().getCollectionPersister( Salesperson.class.getName() + ".orders" ); - assertTrue( "No cache for collection", persister.hasCache() ); CollectionDataAccess cache = persister.getCacheAccessStrategy(); - Object cacheKey = cache.generateCacheKey( - testData.steveId, - persister, - sessionFactory(), - session.getTenantIdentifier() + + CollectionCacheEntry cachedData = fromSession( + session -> { + long ts = session.getTimestamp(); + + // Force a collection into the second level cache, with its non-filtered elements + Salesperson sp = session.load( Salesperson.class, testData.steveId ); + Hibernate.initialize( sp.getOrders() ); + assertTrue( "No cache for collection", persister.hasCache() ); + Object cacheKey = cache.generateCacheKey( + testData.steveId, + persister, + sessionFactory(), + session.getTenantIdentifier() + ); + CollectionCacheEntry cached = (CollectionCacheEntry) cache.get( + session, + cacheKey + ); + assertNotNull( "collection was not in cache", cached ); + return cached; + } ); - CollectionCacheEntry cachedData = ( CollectionCacheEntry ) cache.get( ( SessionImplementor ) session, cacheKey ); - assertNotNull( "collection was not in cache", cachedData ); - session.close(); + inSession( + session -> { + long ts = session.getTimestamp(); + session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + Salesperson sp = (Salesperson) session.createQuery( "from Salesperson as s where s.id = :id" ) + .setParameter( "id", testData.steveId ) + .uniqueResult(); + assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); - session = openSession(); - ts = ( ( SessionImplementor ) session ).getTimestamp(); - session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - sp = ( Salesperson ) session.createQuery( "from Salesperson as s where s.id = :id" ) - .setParameter( "id", testData.steveId ) - .uniqueResult(); - assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); - - Object cacheKey2 = cache.generateCacheKey( - testData.steveId, - persister, - sessionFactory(), - session.getTenantIdentifier() + Object cacheKey2 = cache.generateCacheKey( + testData.steveId, + persister, + sessionFactory(), + session.getTenantIdentifier() + ); + CollectionCacheEntry cachedData2 = (CollectionCacheEntry) persister.getCacheAccessStrategy() + .get( session, cacheKey2 ); + assertNotNull( "collection no longer in cache!", cachedData2 ); + assertSame( "Different cache values!", cachedData, cachedData2 ); + } ); - CollectionCacheEntry cachedData2 = ( CollectionCacheEntry ) persister.getCacheAccessStrategy().get( ( SessionImplementor ) session, cacheKey2 ); - assertNotNull( "collection no longer in cache!", cachedData2 ); - assertSame( "Different cache values!", cachedData, cachedData2 ); - session.close(); - - session = openSession(); - session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - sp = session.load( Salesperson.class, testData.steveId ); - assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); - - session.close(); + inSession( + session -> { + session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + Salesperson sp = session.load( Salesperson.class, testData.steveId ); + assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); + } + ); // Finally, make sure that the original cached version did not get over-written - session = openSession(); - sp = session.load( Salesperson.class, testData.steveId ); - assertEquals( "Actual cached version got over-written", 2, sp.getOrders().size() ); - - session.close(); - testData.release(); + inSession( + session -> { + Salesperson sp = session.load( Salesperson.class, testData.steveId ); + assertEquals( "Actual cached version got over-written", 2, sp.getOrders().size() ); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testCombinedClassAndCollectionFiltersEnabled() { - TestData testData = new TestData(); - testData.prepare(); - Session session = openSession(); - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[]{"LA", "APAC"} ); - session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + inSession( + session -> { + session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "LA", "APAC" } ); + session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - // test retrieval through hql with the collection as non-eager - List salespersons = session.createQuery( "select s from Salesperson as s", Salesperson.class ).getResultList(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - Salesperson sp = salespersons.get( 0 ); - assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); + // test retrieval through hql with the collection as non-eager + List salespersons = session.createQuery( + "select s from Salesperson as s", + Salesperson.class + ) + .getResultList(); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); + Salesperson sp = salespersons.get( 0 ); + assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); - session.clear(); + session.clear(); - session.disableFilter( "regionlist" ); - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[]{"LA", "APAC", "APAC"} ); - // Second test retrieval through hql with the collection as non-eager with different region list - salespersons = session.createQuery( "select s from Salesperson as s", Salesperson.class ).getResultList(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - sp = salespersons.get( 0 ); - assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); + session.disableFilter( "regionlist" ); + session.enableFilter( "regionlist" ).setParameterList( + "regions", + new String[] { "LA", "APAC", "APAC" } + ); + // Second test retrieval through hql with the collection as non-eager with different region list + salespersons = session.createQuery( "select s from Salesperson as s", Salesperson.class ) + .getResultList(); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); + sp = salespersons.get( 0 ); + assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); - session.clear(); + session.clear(); - - // test retrieval through hql with the collection join fetched - salespersons = session.createQuery( "select s from Salesperson as s left join fetch s.orders", Salesperson.class ).getResultList(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - sp = salespersons.get( 0 ); - assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); - - session.close(); - testData.release(); + // test retrieval through hql with the collection join fetched + salespersons = session.createQuery( + "select s from Salesperson as s left join fetch s.orders", + Salesperson.class + ).getResultList(); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); + sp = salespersons.get( 0 ); + assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "not implemented method of QueryParameterBindingsImpl in v6" ) + @FailureExpected(jiraKey = "none", message = "not implemented method of QueryParameterBindingsImpl in v6") public void testHqlFilters() { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HQL test //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info( "Starting HQL filter tests" ); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting HQL filter tests" ); - Session session = openSession(); - session.enableFilter( "region" ).setParameter( "region", "APAC" ); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - session.enableFilter( "effectiveDate" ) - .setParameter( "asOfDate", testData.lastMonth.getTime() ); + session.enableFilter( "effectiveDate" ) + .setParameter( "asOfDate", testData.lastMonth.getTime() ); - log.info( "HQL against Salesperson..." ); - List results = session.createQuery( "select s from Salesperson as s left join fetch s.orders" ).list(); - assertTrue( "Incorrect filtered HQL result count [" + results.size() + "]", results.size() == 1 ); - Salesperson result = ( Salesperson ) results.get( 0 ); - assertTrue( "Incorrect collectionfilter count", result.getOrders().size() == 1 ); + log.info( "HQL against Salesperson..." ); + List results = session.createQuery( "select s from Salesperson as s left join fetch s.orders" ) + .list(); + assertTrue( "Incorrect filtered HQL result count [" + results.size() + "]", results.size() == 1 ); + Salesperson result = (Salesperson) results.get( 0 ); + assertTrue( "Incorrect collectionfilter count", result.getOrders().size() == 1 ); - log.info( "HQL against Product..." ); - results = session.createQuery( "from Product as p where p.stockNumber = ?1" ).setParameter( 1, 124 ).list(); - assertTrue( results.size() == 1 ); - - session.close(); - testData.release(); + log.info( "HQL against Product..." ); + results = session.createQuery( "from Product as p where p.stockNumber = ?1" ) + .setParameter( 1, 124 ) + .list(); + assertTrue( results.size() == 1 ); + } + ); } @Test @@ -228,18 +257,16 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Custom SQL read/write with filter //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info( "Starting HQL filter with custom SQL get/set tests" ); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting HQL filter with custom SQL get/set tests" ); - Session session = openSession(); - session.enableFilter( "heavyProducts" ).setParameter( "weightKilograms", 4d ); - log.info( "HQL against Product..." ); - List results = session.createQuery( "from Product", Product.class ).getResultList(); - assertEquals( 1, results.size() ); - - session.close(); - testData.release(); + inSession( + session -> { + session.enableFilter( "heavyProducts" ).setParameter( "weightKilograms", 4d ); + log.info( "HQL against Product..." ); + List results = session.createQuery( "from Product", Product.class ).getResultList(); + assertEquals( 1, results.size() ); + } + ); } @Test @@ -247,51 +274,48 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Criteria-query test //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting Criteria-query filter tests"); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting Criteria-query filter tests" ); - Session session = openSession(); - session.enableFilter( "region" ).setParameter( "region", "APAC" ); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - session.enableFilter( "fulfilledOrders" ) - .setParameter( "asOfDate", testData.lastMonth.getTime() ); + session.enableFilter( "fulfilledOrders" ) + .setParameter( "asOfDate", testData.lastMonth.getTime() ); - session.enableFilter( "effectiveDate" ) - .setParameter( "asOfDate", testData.lastMonth.getTime() ); + session.enableFilter( "effectiveDate" ) + .setParameter( "asOfDate", testData.lastMonth.getTime() ); - log.info( "Criteria query against Salesperson..." ); - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( Salesperson.class ); - Root from = criteria.from( Salesperson.class ); - from.fetch( "orders", JoinType.LEFT ); - List salespersons = session.createQuery( criteria ).getResultList(); + log.info( "Criteria query against Salesperson..." ); + CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + CriteriaQuery criteria = criteriaBuilder.createQuery( Salesperson.class ); + Root from = criteria.from( Salesperson.class ); + from.fetch( "orders", JoinType.LEFT ); + List salespersons = session.createQuery( criteria ).getResultList(); // List salespersons = session.createCriteria( Salesperson.class ) // .setFetchMode( "orders", FetchMode.JOIN ) // .list(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - assertEquals( "Incorrect order count", 1, ( salespersons.get( 0 ) ).getOrders().size() ); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); + assertEquals( "Incorrect order count", 1, ( salespersons.get( 0 ) ).getOrders().size() ); - log.info( "Criteria query against Product..." ); - CriteriaQuery productCriteria = criteriaBuilder.createQuery( Product.class ); - Root productRoot = productCriteria.from( Product.class ); - productCriteria.where( criteriaBuilder.equal( productRoot.get( "stockNumber" ), 124 ) ); + log.info( "Criteria query against Product..." ); + CriteriaQuery productCriteria = criteriaBuilder.createQuery( Product.class ); + Root productRoot = productCriteria.from( Product.class ); + productCriteria.where( criteriaBuilder.equal( productRoot.get( "stockNumber" ), 124 ) ); - List products = session.createQuery( productCriteria ).getResultList(); + List products = session.createQuery( productCriteria ).getResultList(); // List products = session.createCriteria( Product.class ) // .add( Restrictions.eq( "stockNumber", 124 ) ) // .list(); - assertEquals( "Incorrect product count", 1, products.size() ); + assertEquals( "Incorrect product count", 1, products.size() ); - session.close(); - testData.release(); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testCriteriaControl() { - TestData testData = new TestData(); - testData.prepare(); // the subquery... // DetachedCriteria subquery = DetachedCriteria.forClass( Salesperson.class ) @@ -305,7 +329,7 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { inTransaction( session -> { session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] {"APAC"} ); + session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } ); CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery criteria = criteriaBuilder.createQuery( Order.class ); @@ -319,122 +343,127 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { assertEquals( 1, result.size() ); } ); - - testData.release(); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testCriteriaSubqueryWithFilters() { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Criteria-subquery test //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting Criteria-subquery filter tests"); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting Criteria-subquery filter tests" ); - Session session = openSession(); - session.enableFilter("region").setParameter("region", "APAC"); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - log.info("Criteria query against Department with a subquery on Salesperson in the APAC reqion..."); + log.info( "Criteria query against Department with a subquery on Salesperson in the APAC reqion..." ); // DetachedCriteria salespersonSubquery = DetachedCriteria.forClass(Salesperson.class) // .add(Restrictions.eq("name", "steve")) // .setProjection(Property.forName("department")); - CriteriaBuilder detachedCriteriaBuilder = sessionFactory().getCriteriaBuilder(); - Subquery subquery = detachedCriteriaBuilder.createQuery( Salesperson.class ).subquery( Department.class ); - Root subqueryRoot = subquery.from( Salesperson.class ); - subquery.where( detachedCriteriaBuilder.equal( subqueryRoot.get("name"), "steve") ); - subquery.select( subqueryRoot.get( "department" ) ); + CriteriaBuilder detachedCriteriaBuilder = sessionFactory().getCriteriaBuilder(); + Subquery subquery = detachedCriteriaBuilder.createQuery( Salesperson.class ) + .subquery( Department.class ); + Root subqueryRoot = subquery.from( Salesperson.class ); + subquery.where( detachedCriteriaBuilder.equal( subqueryRoot.get( "name" ), "steve" ) ); + subquery.select( subqueryRoot.get( "department" ) ); - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( Department.class ); - criteria.where( criteriaBuilder.in( criteria.from( Department.class ).get( "id" ) ).value( subquery ) ); + CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + CriteriaQuery criteria = criteriaBuilder.createQuery( Department.class ); + criteria.where( criteriaBuilder.in( criteria.from( Department.class ).get( "id" ) ) + .value( subquery ) ); - Query departmentsQuery = session.createQuery( criteria ); - List departments = departmentsQuery.list(); + Query departmentsQuery = session.createQuery( criteria ); + List departments = departmentsQuery.list(); // Criteria departmentsQuery = session.createCriteria(Department.class).add(Subqueries.propertyIn("id", salespersonSubquery)); // List departments = departmentsQuery.list(); - assertEquals("Incorrect department count", 1, departments.size()); + assertEquals( "Incorrect department count", 1, departments.size() ); - log.info("Criteria query against Department with a subquery on Salesperson in the FooBar reqion..."); + log.info( "Criteria query against Department with a subquery on Salesperson in the FooBar reqion..." ); - session.enableFilter("region").setParameter("region", "Foobar"); - departments = departmentsQuery.list(); + session.enableFilter( "region" ).setParameter( "region", "Foobar" ); + departments = departmentsQuery.list(); - assertEquals("Incorrect department count", 0, departments.size()); + assertEquals( "Incorrect department count", 0, departments.size() ); - log.info("Criteria query against Order with a subquery for line items with a subquery on product and sold by a given sales person..."); - session.enableFilter("region").setParameter("region", "APAC"); + log.info( + "Criteria query against Order with a subquery for line items with a subquery on product and sold by a given sales person..." ); + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - Subquery lineItemSubquery = detachedCriteriaBuilder.createQuery().subquery( LineItem.class ); - Root itemRoot = lineItemSubquery.from( LineItem.class ); - Join product = itemRoot.join( "product", JoinType.INNER ); - lineItemSubquery.where( - detachedCriteriaBuilder.and( - detachedCriteriaBuilder.ge( itemRoot.get( "quantity" ), 1L ), - detachedCriteriaBuilder.equal( product.get( "name" ), "Acme Hair Gel" ) - ) - ); - lineItemSubquery.select( product.get( "id" ) ); + Subquery lineItemSubquery = detachedCriteriaBuilder.createQuery() + .subquery( LineItem.class ); + Root itemRoot = lineItemSubquery.from( LineItem.class ); + Join product = itemRoot.join( "product", JoinType.INNER ); + lineItemSubquery.where( + detachedCriteriaBuilder.and( + detachedCriteriaBuilder.ge( itemRoot.get( "quantity" ), 1L ), + detachedCriteriaBuilder.equal( product.get( "name" ), "Acme Hair Gel" ) + ) + ); + lineItemSubquery.select( product.get( "id" ) ); // DetachedCriteria lineItemSubquery = DetachedCriteria.forClass(LineItem.class) // .add( Restrictions.ge( "quantity", 1L ) ) // .createCriteria( "product" ) // .add( Restrictions.eq( "name", "Acme Hair Gel" ) ) // .setProjection( Property.forName( "id" ) ); - CriteriaQuery orderCriteria = criteriaBuilder.createQuery( Order.class ); - Root orderRoot = orderCriteria.from( Order.class ); - orderCriteria.where( - criteriaBuilder.and( - criteriaBuilder.exists( lineItemSubquery ), - criteriaBuilder.equal( orderRoot.get( "buyer"),"gavin" ) - ) - ); + CriteriaQuery orderCriteria = criteriaBuilder.createQuery( Order.class ); + Root orderRoot = orderCriteria.from( Order.class ); + orderCriteria.where( + criteriaBuilder.and( + criteriaBuilder.exists( lineItemSubquery ), + criteriaBuilder.equal( orderRoot.get( "buyer" ), "gavin" ) + ) + ); - List orders = session.createQuery( orderCriteria ).list(); + List orders = session.createQuery( orderCriteria ).list(); // List orders = session.createCriteria(Order.class) // .add(Subqueries.exists(lineItemSubquery)) // .add(Restrictions.eq("buyer", "gavin")) // .list(); - assertEquals("Incorrect orders count", 1, orders.size()); + assertEquals( "Incorrect orders count", 1, orders.size() ); - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month"); - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime()); + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month" ); + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - Subquery productSubquery = detachedCriteriaBuilder.createQuery().subquery( Product.class ); - Root productRoot = productSubquery.from( Product.class ); - productSubquery.select( productRoot.get( "id" ) ); - productSubquery.where( detachedCriteriaBuilder.equal( productRoot.get( "name" ), "Acme Hair Gel" ) ); + Subquery productSubquery = detachedCriteriaBuilder.createQuery().subquery( Product.class ); + Root productRoot = productSubquery.from( Product.class ); + productSubquery.select( productRoot.get( "id" ) ); + productSubquery.where( detachedCriteriaBuilder.equal( + productRoot.get( "name" ), + "Acme Hair Gel" + ) ); // DetachedCriteria productSubquery = DetachedCriteria.forClass(Product.class) // .add(Restrictions.eq("name", "Acme Hair Gel")) // .setProjection(Property.forName("id")); - lineItemSubquery = detachedCriteriaBuilder.createQuery().subquery( LineItem.class ); - itemRoot = lineItemSubquery.from( LineItem.class ); - product = itemRoot.join( "product", JoinType.INNER ); - lineItemSubquery.where( - detachedCriteriaBuilder.and( - detachedCriteriaBuilder.ge( itemRoot.get( "quantity" ), 1L ), - detachedCriteriaBuilder.in( product.get( "id" ) ).value( productSubquery ) - ) - ); - lineItemSubquery.select( product.get( "id" ) ); + lineItemSubquery = detachedCriteriaBuilder.createQuery().subquery( LineItem.class ); + itemRoot = lineItemSubquery.from( LineItem.class ); + product = itemRoot.join( "product", JoinType.INNER ); + lineItemSubquery.where( + detachedCriteriaBuilder.and( + detachedCriteriaBuilder.ge( itemRoot.get( "quantity" ), 1L ), + detachedCriteriaBuilder.in( product.get( "id" ) ).value( productSubquery ) + ) + ); + lineItemSubquery.select( product.get( "id" ) ); - orderCriteria = criteriaBuilder.createQuery( Order.class ); - orderRoot = orderCriteria.from( Order.class ); - orderCriteria.where( - criteriaBuilder.and( - criteriaBuilder.exists( lineItemSubquery ), - criteriaBuilder.equal( orderRoot.get( "buyer" ), "gavin" ) - ) - ); + orderCriteria = criteriaBuilder.createQuery( Order.class ); + orderRoot = orderCriteria.from( Order.class ); + orderCriteria.where( + criteriaBuilder.and( + criteriaBuilder.exists( lineItemSubquery ), + criteriaBuilder.equal( orderRoot.get( "buyer" ), "gavin" ) + ) + ); - orders = session.createQuery( orderCriteria ).list(); + orders = session.createQuery( orderCriteria ).list(); // lineItemSubquery = DetachedCriteria.forClass(LineItem.class) // .add(Restrictions.ge("quantity", 1L )) // .createCriteria("product") @@ -446,246 +475,260 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { // .add(Restrictions.eq("buyer", "gavin")) // .list(); - assertEquals("Incorrect orders count", 1, orders.size()); + assertEquals( "Incorrect orders count", 1, orders.size() ); - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of 4 months ago"); - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter("asOfDate", testData.fourMonthsAgo.getTime()); + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of 4 months ago" ); + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( + "asOfDate", + testData.fourMonthsAgo.getTime() + ); - orderCriteria = criteriaBuilder.createQuery( Order.class ); - orderRoot = orderCriteria.from( Order.class ); - orderCriteria.where( - criteriaBuilder.and( - criteriaBuilder.exists( lineItemSubquery ), - criteriaBuilder.equal( orderRoot.get( "buyer" ), "gavin" ) - ) - ); + orderCriteria = criteriaBuilder.createQuery( Order.class ); + orderRoot = orderCriteria.from( Order.class ); + orderCriteria.where( + criteriaBuilder.and( + criteriaBuilder.exists( lineItemSubquery ), + criteriaBuilder.equal( orderRoot.get( "buyer" ), "gavin" ) + ) + ); - orders = session.createQuery( orderCriteria ).list(); + orders = session.createQuery( orderCriteria ).list(); // orders = session.createCriteria(Order.class) // .add(Subqueries.exists(lineItemSubquery)) // .add(Restrictions.eq("buyer", "gavin")) // .list(); - assertEquals("Incorrect orders count", 0, orders.size()); + assertEquals( "Incorrect orders count", 0, orders.size() ); + + } + ); - session.close(); - testData.release(); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testHQLSubqueryWithFilters() { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HQL subquery with filters test //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting HQL subquery with filters tests"); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting HQL subquery with filters tests" ); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - Session session = openSession(); - session.enableFilter("region").setParameter("region", "APAC"); + log.info( "query against Department with a subquery on Salesperson in the APAC reqion..." ); - log.info("query against Department with a subquery on Salesperson in the APAC reqion..."); + List departments = session.createQuery( + "select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?1)" + ).setParameter( 1, "steve" ).list(); - List departments = session.createQuery( - "select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?1)" - ).setParameter( 1, "steve" ).list(); + assertEquals( "Incorrect department count", 1, departments.size() ); - assertEquals("Incorrect department count", 1, departments.size()); + log.info( "query against Department with a subquery on Salesperson in the FooBar reqion..." ); - log.info("query against Department with a subquery on Salesperson in the FooBar reqion..."); + session.enableFilter( "region" ).setParameter( "region", "Foobar" ); + departments = session.createQuery( + "select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?1)" ) + .setParameter( 1, "steve" ) + .list(); - session.enableFilter("region").setParameter( "region", "Foobar" ); - departments = session.createQuery("select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?1)").setParameter(1, "steve").list(); + assertEquals( "Incorrect department count", 0, departments.size() ); - assertEquals( "Incorrect department count", 0, departments.size() ); + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region for a given buyer" ); + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region for a given buyer"); - session.enableFilter("region").setParameter( "region", "APAC" ); + List orders = session.createQuery( + "select o from Order as o where exists (select li.id from LineItem li, Product as p where p.id = li.product and li.quantity >= ?1 and p.name = ?2) and o.buyer = ?3" ) + .setParameter( 1, 1L ).setParameter( 2, "Acme Hair Gel" ).setParameter( 3, "gavin" ).list(); - List orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li, Product as p where p.id = li.product and li.quantity >= ?1 and p.name = ?2) and o.buyer = ?3") - .setParameter(1, 1L).setParameter(2, "Acme Hair Gel").setParameter(3, "gavin").list(); + assertEquals( "Incorrect orders count", 1, orders.size() ); - assertEquals( "Incorrect orders count", 1, orders.size() ); + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month" ); - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month"); + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter( "asOfDate", testData.lastMonth.getTime() ); + orders = session.createQuery( + "select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3" ) + .setParameter( 1, 1L ).setParameter( 2, "Acme Hair Gel" ).setParameter( 3, "gavin" ).list(); - orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3") - .setParameter(1, 1L).setParameter(2, "Acme Hair Gel").setParameter(3, "gavin").list(); - - assertEquals( "Incorrect orders count", 1, orders.size() ); + assertEquals( "Incorrect orders count", 1, orders.size() ); - log.info( - "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of 4 months ago" + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of 4 months ago" + ); + + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( + "asOfDate", + testData.fourMonthsAgo.getTime() + ); + + orders = session.createQuery( + "select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3" ) + .setParameter( 1, 1L ).setParameter( 2, "Acme Hair Gel" ).setParameter( 3, "gavin" ).list(); + + assertEquals( "Incorrect orders count", 0, orders.size() ); + + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month with named types" ); + + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + + orders = session.createQuery( + "select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3" ) + .setParameter( 1, 1L ).setParameter( 2, "Acme Hair Gel" ).setParameter( 3, "gavin" ).list(); + + assertEquals( "Incorrect orders count", 1, orders.size() ); + + log.info( + "query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month with mixed types" ); + + session.enableFilter( "region" ).setParameter( "region", "APAC" ); + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + + orders = session.createQuery( + "select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3" ) + .setParameter( 1, 1L ).setParameter( 2, "Acme Hair Gel" ).setParameter( 3, "gavin" ).list(); + + assertEquals( "Incorrect orders count", 1, orders.size() ); + + } ); - - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter("asOfDate", testData.fourMonthsAgo.getTime()); - - orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3") - .setParameter(1, 1L).setParameter(2, "Acme Hair Gel").setParameter(3, "gavin").list(); - - assertEquals("Incorrect orders count", 0, orders.size()); - - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month with named types"); - - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime()); - - orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3") - .setParameter(1, 1L).setParameter(2, "Acme Hair Gel").setParameter(3, "gavin").list(); - - assertEquals("Incorrect orders count", 1, orders.size()); - - log.info("query against Order with a subquery for line items with a subquery line items where the product name is Acme Hair Gel and the quantity is greater than 1 in a given region and the product is effective as of last month with mixed types"); - - session.enableFilter("region").setParameter("region", "APAC"); - session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime()); - - orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ?1 and li.product in (select p.id from Product p where p.name = ?2)) and o.buyer = ?3") - .setParameter(1, 1L).setParameter(2, "Acme Hair Gel").setParameter(3, "gavin").list(); - - assertEquals("Incorrect orders count", 1, orders.size()); - - session.close(); - testData.release(); } @Test - @TestForIssue( jiraKey = "HHH-5932" ) + @TestForIssue(jiraKey = "HHH-5932") public void testHqlQueryWithColons() { - final Session session = openSession(); - session.enableFilter( "region" ).setParameter( "region", "PACA" ); - session.createQuery( "from Salesperson p where p.name = ':hibernate'" ).list(); - session.close(); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "PACA" ); + session.createQuery( "from Salesperson p where p.name = ':hibernate'" ).list(); + + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testFilterApplicationOnHqlQueryWithImplicitSubqueryContainingPositionalParameter() { - TestData testData = new TestData(); - testData.prepare(); + inTransaction( + session -> { + final String queryString = "from Order o where ?1 in ( select sp.name from Salesperson sp )"; - Session session = openSession(); - session.beginTransaction(); + // first a control-group query + List result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); + assertEquals( 2, result.size() ); - final String queryString = "from Order o where ?1 in ( select sp.name from Salesperson sp )"; + // now lets enable filters on Order... + session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); + assertEquals( 1, result.size() ); - // first a control-group query - List result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); - assertEquals( 2, result.size() ); + // now, lets additionally enable filter on Salesperson. First a valid one... + session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } ); + result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); + assertEquals( 1, result.size() ); - // now lets enable filters on Order... - session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); - assertEquals( 1, result.size() ); - - // now, lets additionally enable filter on Salesperson. First a valid one... - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } ); - result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); - assertEquals( 1, result.size() ); - - // ... then a silly one... - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "gamma quadrant" } ); - result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); - assertEquals( 0, result.size() ); - - session.getTransaction().commit(); - session.close(); - - testData.release(); + // ... then a silly one... + session.enableFilter( "regionlist" ).setParameterList( + "regions", + new String[] { "gamma quadrant" } + ); + result = session.createQuery( queryString ).setParameter( 1, "steve" ).list(); + assertEquals( 0, result.size() ); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testFilterApplicationOnHqlQueryWithImplicitSubqueryContainingNamedParameter() { - TestData testData = new TestData(); - testData.prepare(); + inTransaction( + session -> { + final String queryString = "from Order o where :salesPersonName in ( select sp.name from Salesperson sp )"; - Session session = openSession(); - session.beginTransaction(); + // first a control-group query + List result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); + assertEquals( 2, result.size() ); - final String queryString = "from Order o where :salesPersonName in ( select sp.name from Salesperson sp )"; + // now lets enable filters on Order... + session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); + result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); + assertEquals( 1, result.size() ); - // first a control-group query - List result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); - assertEquals( 2, result.size() ); + // now, lets additionally enable filter on Salesperson. First a valid one... + session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } ); + result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); + assertEquals( 1, result.size() ); - // now lets enable filters on Order... - session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); - result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); - assertEquals( 1, result.size() ); + // ... then a silly one... + session.enableFilter( "regionlist" ).setParameterList( + "regions", + new String[] { "gamma quadrant" } + ); + result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); + assertEquals( 0, result.size() ); - // now, lets additionally enable filter on Salesperson. First a valid one... - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } ); - result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); - assertEquals( 1, result.size() ); - - // ... then a silly one... - session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "gamma quadrant" } ); - result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list(); - assertEquals( 0, result.size() ); - - session.getTransaction().commit(); - session.close(); - - testData.release(); + } + ); } @Test public void testFiltersOnSimpleHqlDelete() { - Session session = openSession(); - session.beginTransaction(); Salesperson sp = new Salesperson(); - sp.setName( "steve" ); - sp.setRegion( "NA" ); - session.persist( sp ); Salesperson sp2 = new Salesperson(); - sp2.setName( "john" ); - sp2.setRegion( "APAC" ); - session.persist( sp2 ); - session.getTransaction().commit(); - session.close(); + inTransaction( + session -> { + sp.setName( "steve" ); + sp.setRegion( "NA" ); + session.persist( sp ); + sp2.setName( "john" ); + sp2.setRegion( "APAC" ); + session.persist( sp2 ); + } + ); - session = openSession(); - session.beginTransaction(); - session.enableFilter( "region" ).setParameter( "region", "NA" ); - int count = session.createQuery( "delete from Salesperson" ).executeUpdate(); - assertEquals( 1, count ); - session.delete( sp2 ); - session.getTransaction().commit(); - session.close(); + inTransaction( + session -> { + session.enableFilter( "region" ).setParameter( "region", "NA" ); + int count = session.createQuery( "delete from Salesperson" ).executeUpdate(); + assertEquals( 1, count ); + session.delete( sp2 ); + } + ); } @Test public void testFiltersOnMultiTableHqlDelete() { - Session session = openSession(); - session.beginTransaction(); Salesperson sp = new Salesperson(); - sp.setName( "steve" ); - sp.setRegion( "NA" ); - session.persist( sp ); Salesperson sp2 = new Salesperson(); - sp2.setName( "john" ); - sp2.setRegion( "APAC" ); - session.persist( sp2 ); - session.getTransaction().commit(); - session.close(); + inTransaction( + session -> { + sp.setName( "steve" ); + sp.setRegion( "NA" ); + session.persist( sp ); + sp2.setName( "john" ); + sp2.setRegion( "APAC" ); + session.persist( sp2 ); + } + ); - session = openSession(); - session.beginTransaction(); - session.enableFilter( "region" ).setParameter( "region", "NA" ); - int count = session.createQuery( "delete from Salesperson" ).executeUpdate(); - assertEquals( 1, count ); - session.delete( sp2 ); - session.getTransaction().commit(); - session.close(); + inTransaction( + session -> { + session.enableFilter( "region" ).setParameter( "region", "NA" ); + int count = session.createQuery( "delete from Salesperson" ).executeUpdate(); + assertEquals( 1, count ); + session.delete( sp2 ); + } + ); } @Test @@ -693,20 +736,19 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Get() test //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting get() filter tests (eager assoc. fetching)."); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting get() filter tests (eager assoc. fetching)." ); - Session session = openSession(); - session.enableFilter( "region" ).setParameter( "region", "APAC" ); + inSession( + session -> { + session.enableFilter( "region" ).setParameter( "region", "APAC" ); - log.info("Performing get()..."); - Salesperson salesperson = session.get( Salesperson.class, testData.steveId ); - assertNotNull( salesperson ); - assertEquals( "Incorrect order count", 1, salesperson.getOrders().size() ); + log.info( "Performing get()..." ); + Salesperson salesperson = session.get( Salesperson.class, testData.steveId ); + assertNotNull( salesperson ); + assertEquals( "Incorrect order count", 1, salesperson.getOrders().size() ); - session.close(); - testData.release(); + } + ); } @Test @@ -714,255 +756,244 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // one-to-many loading tests //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting one-to-many collection loader filter tests."); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting one-to-many collection loader filter tests." ); + inSession( + session -> { + session.enableFilter( "seniorSalespersons" ) + .setParameter( "asOfDate", testData.lastMonth.getTime() ); - Session session = openSession(); - session.enableFilter( "seniorSalespersons" ) - .setParameter( "asOfDate", testData.lastMonth.getTime() ); + log.info( "Performing load of Department..." ); + Department department = session.load( Department.class, testData.deptId ); + Set salespersons = department.getSalespersons(); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - log.info("Performing load of Department..."); - Department department = session.load( Department.class, testData.deptId ); - Set salespersons = department.getSalespersons(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - - session.close(); - testData.release(); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testInStyleFilterParameter() { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // one-to-many loading tests //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - log.info("Starting one-to-many collection loader filter tests."); - TestData testData = new TestData(); - testData.prepare(); + log.info( "Starting one-to-many collection loader filter tests." ); + inSession( + session -> { + session.enableFilter( "regionlist" ) + .setParameterList( "regions", new String[] { "LA", "APAC" } ); - Session session = openSession(); - session.enableFilter( "regionlist" ) - .setParameterList( "regions", new String[]{"LA", "APAC"} ); + log.debug( "Performing query of Salespersons" ); + List salespersons = session.createQuery( "from Salesperson" ).list(); + assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - log.debug("Performing query of Salespersons"); - List salespersons = session.createQuery( "from Salesperson" ).list(); - assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); - - session.close(); - testData.release(); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testManyToManyFilterOnCriteria() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); - Session session = openSession(); - session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); + CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + CriteriaQuery criteria = criteriaBuilder.createQuery( Product.class ); + Root root = criteria.from( Product.class ); + criteria.where( criteriaBuilder.equal( root.get( "id" ), testData.prod1Id ) ); - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( Product.class ); - Root root = criteria.from( Product.class ); - criteria.where( criteriaBuilder.equal( root.get( "id" ), testData.prod1Id ) ); - - Product prod = session.createQuery( criteria ) - .setResultTransformer( DistinctRootEntityResultTransformer.INSTANCE ) - .uniqueResult(); + Product prod = session.createQuery( criteria ) + .setResultTransformer( DistinctRootEntityResultTransformer.INSTANCE ) + .uniqueResult(); // Product prod = ( Product ) session.createCriteria( Product.class ) // .setResultTransformer( DistinctRootEntityResultTransformer.INSTANCE ) // .add( Restrictions.eq( "id", testData.prod1Id ) ) // .uniqueResult(); - assertNotNull( prod ); - assertEquals( "Incorrect Product.categories count for filter", 1, prod.getCategories().size() ); - - session.close(); - testData.release(); + assertNotNull( prod ); + assertEquals( "Incorrect Product.categories count for filter", 1, prod.getCategories().size() ); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testManyToManyFilterOnLoad() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); - Session session = openSession(); - session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); + Product prod = session.get( Product.class, testData.prod1Id ); - Product prod = session.get( Product.class, testData.prod1Id ); + long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + // should already have been initialized... + int size = prod.getCategories().size(); + assertEquals( "Incorrect filtered collection count", 1, size ); - // should already have been initialized... - int size = prod.getCategories().size(); - assertEquals( "Incorrect filtered collection count", 1, size ); + long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + assertTrue( + "load with join fetch of many-to-many did not trigger join fetch", + ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + ); - assertTrue( - "load with join fetch of many-to-many did not trigger join fetch", - ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + // make sure we did not get back a collection of proxies + long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); + for ( Object o : prod.getCategories() ) { + Category cat = (Category) o; + System.out.println( " ===> " + cat.getName() ); + } + long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); + + assertTrue( + "load with join fetch of many-to-many did not trigger *complete* join fetch", + ( initEntityLoadCount == currEntityLoadCount ) + ); + } ); - - // make sure we did not get back a collection of proxies - long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - for ( Object o : prod.getCategories() ) { - Category cat = (Category) o; - System.out.println( " ===> " + cat.getName() ); - } - long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - - assertTrue( - "load with join fetch of many-to-many did not trigger *complete* join fetch", - ( initEntityLoadCount == currEntityLoadCount ) - ); - - session.close(); - testData.release(); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testManyToManyOnCollectionLoadAfterHQL() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); - Session session = openSession(); - session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); + // Force the categories to not get initialized here + List result = session.createQuery( "from Product as p where p.id = :id", Product.class ) + .setParameter( "id", testData.prod1Id ) + .getResultList(); + assertFalse( "No products returned from HQL", result.isEmpty() ); - // Force the categories to not get initialized here - List result = session.createQuery( "from Product as p where p.id = :id", Product.class ) - .setParameter( "id", testData.prod1Id ) - .getResultList(); - assertFalse( "No products returned from HQL", result.isEmpty() ); - - Product prod = ( Product ) result.get( 0 ); - assertNotNull( prod ); - assertEquals( "Incorrect Product.categories count for filter on collection load", 1, prod.getCategories().size() ); - - session.close(); - testData.release(); + Product prod = result.get( 0 ); + assertNotNull( prod ); + assertEquals( + "Incorrect Product.categories count for filter on collection load", + 1, + prod.getCategories().size() + ); + } + ); } @Test - @FailureExpected( jiraKey = "none", message = "v6 imperfection" ) + @FailureExpected(jiraKey = "none", message = "v6 imperfection") public void testManyToManyFilterOnQuery() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); - Session session = openSession(); - session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date() ); + List result = session.createQuery( + "from Product p inner join fetch p.categories", + Product.class + ) + .getResultList(); + assertFalse( "No products returned from HQL many-to-many filter case", result.isEmpty() ); - List result = session.createQuery( "from Product p inner join fetch p.categories", Product.class ).getResultList(); - assertFalse( "No products returned from HQL many-to-many filter case", result.isEmpty() ); + Product prod = result.get( 0 ); - Product prod = result.get( 0 ); - - assertNotNull( prod ); - assertEquals( "Incorrect Product.categories count for filter with HQL", 1, prod.getCategories().size() ); - - session.close(); - testData.release(); + assertNotNull( prod ); + assertEquals( + "Incorrect Product.categories count for filter with HQL", + 1, + prod.getCategories().size() + ); + } + ); } @Test public void testManyToManyBase() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + Product prod = session.get( Product.class, testData.prod1Id ); - Session session = openSession(); + long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - Product prod = session.get( Product.class, testData.prod1Id ); + // should already have been initialized... + int size = prod.getCategories().size(); + assertEquals( "Incorrect non-filtered collection count", 2, size ); - long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - // should already have been initialized... - int size = prod.getCategories().size(); - assertEquals( "Incorrect non-filtered collection count", 2, size ); + assertTrue( + "load with join fetch of many-to-many did not trigger join fetch", + ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + ); - long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + // make sure we did not get back a collection of proxies + long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); + for ( Object o : prod.getCategories() ) { + Category cat = (Category) o; + System.out.println( " ===> " + cat.getName() ); + } + long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - assertTrue( - "load with join fetch of many-to-many did not trigger join fetch", - ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + assertTrue( + "load with join fetch of many-to-many did not trigger *complete* join fetch", + ( initEntityLoadCount == currEntityLoadCount ) + ); + } ); - - // make sure we did not get back a collection of proxies - long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - for ( Object o : prod.getCategories() ) { - Category cat = (Category) o; - System.out.println( " ===> " + cat.getName() ); - } - long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - - assertTrue( - "load with join fetch of many-to-many did not trigger *complete* join fetch", - ( initEntityLoadCount == currEntityLoadCount ) - ); - - session.close(); - testData.release(); } @Test public void testManyToManyBaseThruCriteria() { - TestData testData = new TestData(); - testData.prepare(); + inSession( + session -> { + CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + CriteriaQuery criteria = criteriaBuilder.createQuery( Product.class ); + Root root = criteria.from( Product.class ); + criteria.where( criteriaBuilder.equal( root.get( "id" ), testData.prod1Id ) ); - Session session = openSession(); - - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( Product.class ); - Root root = criteria.from( Product.class ); - criteria.where( criteriaBuilder.equal( root.get( "id" ), testData.prod1Id ) ); - - List result = session.createQuery( criteria ).list(); + List result = session.createQuery( criteria ).list(); // List result = session.createCriteria( Product.class ) // .add( Restrictions.eq( "id", testData.prod1Id ) ) // .list(); - Product prod = result.get( 0 ); + Product prod = result.get( 0 ); - long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + long initLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long initFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - // should already have been initialized... - int size = prod.getCategories().size(); - assertEquals( "Incorrect non-filtered collection count", 2, size ); + // should already have been initialized... + int size = prod.getCategories().size(); + assertEquals( "Incorrect non-filtered collection count", 2, size ); - long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); - long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); + long currLoadCount = sessionFactory().getStatistics().getCollectionLoadCount(); + long currFetchCount = sessionFactory().getStatistics().getCollectionFetchCount(); - assertTrue( - "load with join fetch of many-to-many did not trigger join fetch", - ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + assertTrue( + "load with join fetch of many-to-many did not trigger join fetch", + ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) + ); + + // make sure we did not get back a collection of proxies + long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); + for ( Object o : prod.getCategories() ) { + Category cat = (Category) o; + System.out.println( " ===> " + cat.getName() ); + } + long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); + + assertTrue( + "load with join fetch of many-to-many did not trigger *complete* join fetch", + ( initEntityLoadCount == currEntityLoadCount ) + ); + } ); - - // make sure we did not get back a collection of proxies - long initEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - for ( Object o : prod.getCategories() ) { - Category cat = (Category) o; - System.out.println( " ===> " + cat.getName() ); - } - long currEntityLoadCount = sessionFactory().getStatistics().getEntityLoadCount(); - - assertTrue( - "load with join fetch of many-to-many did not trigger *complete* join fetch", - ( initEntityLoadCount == currEntityLoadCount ) - ); - - session.close(); - testData.release(); } + private class TestData { private Long steveId; private Long deptId; @@ -975,122 +1006,118 @@ public class DynamicFilterTest extends BaseNonConfigCoreFunctionalTestCase { private final List entitiesToCleanUp = new ArrayList<>(); private void prepare() { - Session session = openSession(); - Transaction transaction = session.beginTransaction(); + inTransaction( + session -> { + lastMonth = new GregorianCalendar(); + lastMonth.add( Calendar.MONTH, -1 ); - lastMonth = new GregorianCalendar(); - lastMonth.add( Calendar.MONTH, -1 ); + nextMonth = new GregorianCalendar(); + nextMonth.add( Calendar.MONTH, 1 ); - nextMonth = new GregorianCalendar(); - nextMonth.add( Calendar.MONTH, 1 ); + sixMonthsAgo = new GregorianCalendar(); + sixMonthsAgo.add( Calendar.MONTH, -6 ); - sixMonthsAgo = new GregorianCalendar(); - sixMonthsAgo.add( Calendar.MONTH, -6 ); + fourMonthsAgo = new GregorianCalendar(); + fourMonthsAgo.add( Calendar.MONTH, -4 ); - fourMonthsAgo = new GregorianCalendar(); - fourMonthsAgo.add( Calendar.MONTH, -4 ); + Department dept = new Department(); + dept.setName( "Sales" ); - Department dept = new Department(); - dept.setName( "Sales" ); + session.save( dept ); + deptId = dept.getId(); + entitiesToCleanUp.add( dept ); - session.save( dept ); - deptId = dept.getId(); - entitiesToCleanUp.add( dept ); + Salesperson steve = new Salesperson(); + steve.setName( "steve" ); + steve.setRegion( "APAC" ); + steve.setHireDate( sixMonthsAgo.getTime() ); - Salesperson steve = new Salesperson(); - steve.setName( "steve" ); - steve.setRegion( "APAC" ); - steve.setHireDate( sixMonthsAgo.getTime() ); + steve.setDepartment( dept ); + dept.getSalespersons().add( steve ); - steve.setDepartment( dept ); - dept.getSalespersons().add( steve ); + Salesperson max = new Salesperson(); + max.setName( "max" ); + max.setRegion( "EMEA" ); + max.setHireDate( nextMonth.getTime() ); - Salesperson max = new Salesperson(); - max.setName( "max" ); - max.setRegion( "EMEA" ); - max.setHireDate( nextMonth.getTime() ); + max.setDepartment( dept ); + dept.getSalespersons().add( max ); - max.setDepartment( dept ); - dept.getSalespersons().add( max ); + session.save( steve ); + session.save( max ); + entitiesToCleanUp.add( steve ); + entitiesToCleanUp.add( max ); - session.save( steve ); - session.save( max ); - entitiesToCleanUp.add( steve ); - entitiesToCleanUp.add( max ); + steveId = steve.getId(); - steveId = steve.getId(); + Category cat1 = new Category( "test cat 1", lastMonth.getTime(), nextMonth.getTime() ); + Category cat2 = new Category( "test cat 2", sixMonthsAgo.getTime(), fourMonthsAgo.getTime() ); - Category cat1 = new Category( "test cat 1", lastMonth.getTime(), nextMonth.getTime() ); - Category cat2 = new Category( "test cat 2", sixMonthsAgo.getTime(), fourMonthsAgo.getTime() ); + Product product1 = new Product(); + product1.setName( "Acme Hair Gel" ); + product1.setStockNumber( 123 ); + product1.setWeightPounds( 0.25 ); + product1.setEffectiveStartDate( lastMonth.getTime() ); + product1.setEffectiveEndDate( nextMonth.getTime() ); - Product product1 = new Product(); - product1.setName( "Acme Hair Gel" ); - product1.setStockNumber( 123 ); - product1.setWeightPounds( 0.25 ); - product1.setEffectiveStartDate( lastMonth.getTime() ); - product1.setEffectiveEndDate( nextMonth.getTime() ); + product1.addCategory( cat1 ); + product1.addCategory( cat2 ); - product1.addCategory( cat1 ); - product1.addCategory( cat2 ); + session.save( product1 ); + entitiesToCleanUp.add( product1 ); + prod1Id = product1.getId(); - session.save( product1 ); - entitiesToCleanUp.add( product1 ); - prod1Id = product1.getId(); + Order order1 = new Order(); + order1.setBuyer( "gavin" ); + order1.setRegion( "APAC" ); + order1.setPlacementDate( sixMonthsAgo.getTime() ); + order1.setFulfillmentDate( fourMonthsAgo.getTime() ); + order1.setSalesperson( steve ); + order1.addLineItem( product1, 500 ); - Order order1 = new Order(); - order1.setBuyer( "gavin" ); - order1.setRegion( "APAC" ); - order1.setPlacementDate( sixMonthsAgo.getTime() ); - order1.setFulfillmentDate( fourMonthsAgo.getTime() ); - order1.setSalesperson( steve ); - order1.addLineItem( product1, 500 ); + session.save( order1 ); + entitiesToCleanUp.add( order1 ); - session.save( order1 ); - entitiesToCleanUp.add( order1 ); + Product product2 = new Product(); + product2.setName( "Acme Super-Duper DTO Factory" ); + product2.setStockNumber( 124 ); + product1.setWeightPounds( 10.0 ); + product2.setEffectiveStartDate( sixMonthsAgo.getTime() ); + product2.setEffectiveEndDate( new Date() ); - Product product2 = new Product(); - product2.setName( "Acme Super-Duper DTO Factory" ); - product2.setStockNumber( 124 ); - product1.setWeightPounds( 10.0 ); - product2.setEffectiveStartDate( sixMonthsAgo.getTime() ); - product2.setEffectiveEndDate( new Date() ); + Category cat3 = new Category( "test cat 2", sixMonthsAgo.getTime(), new Date() ); + product2.addCategory( cat3 ); - Category cat3 = new Category( "test cat 2", sixMonthsAgo.getTime(), new Date() ); - product2.addCategory( cat3 ); + session.save( product2 ); + entitiesToCleanUp.add( product2 ); - session.save( product2 ); - entitiesToCleanUp.add( product2 ); + // An uncategorized product + Product product3 = new Product(); + product3.setName( "Uncategorized product" ); + session.save( product3 ); + entitiesToCleanUp.add( product3 ); - // An uncategorized product - Product product3 = new Product(); - product3.setName( "Uncategorized product" ); - session.save( product3 ); - entitiesToCleanUp.add( product3 ); + Order order2 = new Order(); + order2.setBuyer( "christian" ); + order2.setRegion( "EMEA" ); + order2.setPlacementDate( lastMonth.getTime() ); + order2.setSalesperson( steve ); + order2.addLineItem( product2, -1 ); - Order order2 = new Order(); - order2.setBuyer( "christian" ); - order2.setRegion( "EMEA" ); - order2.setPlacementDate( lastMonth.getTime() ); - order2.setSalesperson( steve ); - order2.addLineItem( product2, -1 ); - - session.save( order2 ); - entitiesToCleanUp.add( order2 ); - - transaction.commit(); - session.close(); + session.save( order2 ); + entitiesToCleanUp.add( order2 ); + } + ); } private void release() { - Session session = openSession(); - Transaction transaction = session.beginTransaction(); - - for ( Object o : entitiesToCleanUp ) { - session.delete( o ); - } - - transaction.commit(); - session.close(); + inTransaction( + session -> { + for ( Object o : entitiesToCleanUp ) { + session.delete( o ); + } + } + ); } } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/JoinFetchElementCollectionTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/basic/JoinFetchElementCollectionTest.java deleted file mode 100644 index a8790285b6..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/basic/JoinFetchElementCollectionTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.test.collection.basic; - -import java.util.HashSet; -import java.util.Set; - -import org.hibernate.Session; - -import org.hibernate.testing.FailureExpected; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Assert; -import org.junit.Test; - -public class JoinFetchElementCollectionTest extends BaseCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {Contact.class, EmailAddress.class, User.class}; - } - - @Test - @TestForIssue(jiraKey = "HHH-8206") - @FailureExpected(jiraKey = "HHH-8206", message = "This is not explicitly supported, however should arguably throw an exception") - public void testJoinFetchesByPath() { - Set emailAddresses = new HashSet(); - emailAddresses.add( new EmailAddress( "test1@test.com" ) ); - emailAddresses.add( new EmailAddress( "test2@test.com" ) ); - emailAddresses.add( new EmailAddress( "test3@test.com" ) ); - - { - // Session 1: Insert a user with email addresses but no emailAddresses2 - Session session = openSession(); - session.beginTransaction(); - - User user = new User(); - user.setName( "john" ); - Contact contact = new Contact(); - contact.setName( "John Doe" ); - contact.setEmailAddresses( emailAddresses ); - contact = (Contact) session.merge( contact ); - user.setContact( contact ); - user = (User) session.merge( user ); - - session.getTransaction().commit(); - session.close(); - } - { - // Session 2: Retrieve the user object and check if the sets have the expected values - Session session = openSession(); - session.beginTransaction(); - final String qry = "SELECT user " - + "FROM User user " - + "LEFT OUTER JOIN FETCH user.contact " - + "LEFT OUTER JOIN FETCH user.contact.emailAddresses2 " - + "LEFT OUTER JOIN FETCH user.contact.emailAddresses"; - User user = (User) session.createQuery( qry ).uniqueResult(); - session.getTransaction().commit(); - session.close(); - - Assert.assertEquals( emailAddresses, user.getContact().getEmailAddresses() ); - Assert.assertTrue( user.getContact().getEmailAddresses2().isEmpty() ); - } - - } - - @Test - @TestForIssue(jiraKey = "HHH-5465") - public void testJoinFetchElementCollection() { - Set emailAddresses = new HashSet(); - emailAddresses.add( new EmailAddress( "test1@test.com" ) ); - emailAddresses.add( new EmailAddress( "test2@test.com" ) ); - emailAddresses.add( new EmailAddress( "test3@test.com" ) ); - - { - // Session 1: Insert a user with email addresses but no emailAddresses2 - Session session = openSession(); - session.beginTransaction(); - - User user = new User(); - user.setName( "john" ); - Contact contact = new Contact(); - contact.setName( "John Doe" ); - contact.setEmailAddresses( emailAddresses ); - contact = (Contact) session.merge( contact ); - user.setContact( contact ); - user = (User) session.merge( user ); - - session.getTransaction().commit(); - session.close(); - } - { - // Session 2: Retrieve the user object and check if the sets have the expected values - Session session = openSession(); - session.beginTransaction(); - final String qry = "SELECT user " - + "FROM User user " - + "LEFT OUTER JOIN FETCH user.contact c " - + "LEFT OUTER JOIN FETCH c.emailAddresses2 " - + "LEFT OUTER JOIN FETCH c.emailAddresses"; - User user = (User) session.createQuery( qry ).uniqueResult(); - session.getTransaction().commit(); - session.close(); - - Assert.assertEquals( emailAddresses, user.getContact().getEmailAddresses() ); - Assert.assertTrue( user.getContact().getEmailAddresses2().isEmpty() ); - } - - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java deleted file mode 100644 index bd63bbeac7..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationNoCascadeTest.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ - -package org.hibernate.test.collection.delayedOperation; - -import java.util.ArrayList; -import java.util.List; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.collection.internal.AbstractPersistentCollection; -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.assertTrue; - -/** - * Tests delayed operations that are queued for a PersistentBag. The Bag does not have - * to be extra-lazy to queue the operations. - * @author Gail Badner - */ -public class BagDelayedOperationNoCascadeTest extends BaseCoreFunctionalTestCase { - private Long parentId; - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } - - @Before - public void setup() { - // start by cleaning up in case a test fails - if ( parentId != null ) { - cleanup(); - } - - Parent parent = new Parent(); - Child child1 = new Child( "Sherman" ); - Child child2 = new Child( "Yogi" ); - parent.addChild( child1 ); - parent.addChild( child2 ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( child1 ); - s.persist( child2 ); - s.persist( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = parent.getId(); - } - - @After - public void cleanup() { - Session s = openSession(); - s.getTransaction().begin(); - s.createQuery( "delete from Child" ).executeUpdate(); - s.createQuery( "delete from Parent" ).executeUpdate(); - s.getTransaction().commit(); - s.close(); - - parentId = null; - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddManaged() { - // Add 2 Child entities - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Add a managed Child and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the first Child so it is managed; add to collection - p.addChild( s.get( Child.class, c1.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add the other managed Child, merge and commit. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the second Child so it is managed; add to collection - p.addChild( s.get( Child.class, c2.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-11209") - public void testMergeInitializedBagAndRemerge() { - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // initialize - Hibernate.initialize( p.getChildren() ); - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - Child c = new Child( "Zeke" ); - c.setParent( p ); - s.persist( c ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p.getChildren().size(); - p.getChildren().add( c ); - s.getTransaction().commit(); - s.close(); - - // Merge detached Parent with initialized children - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - // after merging, p#children will be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertTrue( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - s.getTransaction().commit(); - assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - s.close(); - - // Merge detached Parent, now with uninitialized children no queued operations - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - s.getTransaction().commit(); - s.close(); - } - - @Entity(name = "Parent") - public static class Parent { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - // Don't need extra-lazy to delay add operations to a bag. - @OneToMany(mappedBy = "parent") - private List children = new ArrayList(); - - public Parent() { - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public List getChildren() { - return children; - } - - public void addChild(Child child) { - children.add(child); - child.setParent(this); - } - } - - @Entity(name = "Child") - public static class Child { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false) - private String name; - - @ManyToOne - private Parent parent; - - public Child() { - } - - public Child(String name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - - @Override - public String toString() { - return "Child{" + - "id=" + id + - ", name='" + name + '\'' + - '}'; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - Child child = (Child) o; - - return name.equals( child.name ); - - } - - @Override - public int hashCode() { - return name.hashCode(); - } - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationTest.java deleted file mode 100644 index b45a252d73..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/BagDelayedOperationTest.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ - -package org.hibernate.test.collection.delayedOperation; - -import java.util.ArrayList; -import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.collection.internal.AbstractPersistentCollection; -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.assertTrue; - -/** - * Tests delayed operations that are queued for a PersistentBag. The Bag does not have - * to be extra-lazy to queue the operations. - * @author Gail Badner - */ -public class BagDelayedOperationTest extends BaseCoreFunctionalTestCase { - private Long parentId; - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } - - @Before - public void setup() { - // start by cleaning up in case a test fails - if ( parentId != null ) { - cleanup(); - } - - Parent parent = new Parent(); - Child child1 = new Child( "Sherman" ); - Child child2 = new Child( "Yogi" ); - parent.addChild( child1 ); - parent.addChild( child2 ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = parent.getId(); - } - - @After - public void cleanup() { - Session s = openSession(); - s.getTransaction().begin(); - Parent parent = s.get( Parent.class, parentId ); - parent.getChildren().clear(); - s.delete( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = null; - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddDetached() { - // Create 2 detached Child objects. - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Now Child c is detached. - - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add detached Child c - p.addChild( c1 ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - // Add a detached Child and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another detached Child, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p.addChild( c2 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p = (Parent) s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddTransient() { - // Add a transient Child and commit. - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Darwin" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another transient Child and commit again. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Comet" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddManaged() { - // Add 2 Child entities - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Add a managed Child and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the first Child so it is managed; add to collection - p.addChild( s.get( Child.class, c1.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add the other managed Child, merge and commit. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the second Child so it is managed; add to collection - p.addChild( s.get( Child.class, c2.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-11209") - public void testMergeInitializedBagAndRemerge() { - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // initialize - Hibernate.initialize( p.getChildren() ); - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - Child c = new Child( "Zeke" ); - c.setParent( p ); - s.persist( c ); - p.getChildren().size(); - p.getChildren().add( c ); - s.getTransaction().commit(); - s.close(); - - // Merge detached Parent with initialized children - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - // after merging, p#children will be initialized - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - s.getTransaction().commit(); - s.close(); - - // Merge detached Parent - s = openSession(); - s.getTransaction().begin(); - p = (Parent) s.merge( p ); - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - assertFalse( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); - s.getTransaction().commit(); - s.close(); - } - - @Entity(name = "Parent") - public static class Parent { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - // Don't need extra-lazy to delay add operations to a bag. - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) - private List children = new ArrayList(); - - public Parent() { - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public List getChildren() { - return children; - } - - public void addChild(Child child) { - children.add(child); - child.setParent(this); - } - } - - @Entity(name = "Child") - public static class Child { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false) - private String name; - - @ManyToOne - private Parent parent; - - public Child() { - } - - public Child(String name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - - @Override - public String toString() { - return "Child{" + - "id=" + id + - ", name='" + name + '\'' + - '}'; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - Child child = (Child) o; - - return name.equals( child.name ); - - } - - @Override - public int hashCode() { - return name.hashCode(); - } - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListAddTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListAddTest.java deleted file mode 100644 index 3d3b5c509b..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListAddTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.test.collection.delayedOperation; - -import java.util.ArrayList; -import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderColumn; -import javax.persistence.Table; - -import org.hibernate.Hibernate; -import org.hibernate.LazyInitializationException; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.collection.spi.PersistentCollection; - -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -/** - * @author Steve Ebersole - */ -public class ListAddTest extends BaseNonConfigCoreFunctionalTestCase { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Quizz.class, Question.class }; - } - - @Before - public void before() { - Session session = sessionFactory().openSession(); - Transaction transaction = session.beginTransaction(); - try { - Quizz quizz = new Quizz( 1 ); - session.persist( quizz ); - quizz.addQuestion( new Question( 1, "question 1" ) ); - quizz.addQuestion( new Question( 2, "question 2" ) ); - quizz.addQuestion( new Question( 3, "question 3" ) ); - - transaction.commit(); - } - finally { - session.close(); - } - } - - @After - public void after() { - Session session = sessionFactory().openSession(); - Transaction transaction = session.beginTransaction(); - session.createQuery( "delete Question" ).executeUpdate(); - session.createQuery( "delete Quizz" ).executeUpdate(); - transaction.commit(); - session.close(); - } - - /** - * This test fails, but shouldn't - */ - @Test - public void addQuestionWithIndexShouldAddQuestionAtSpecifiedIndex() { - Session session = openSession(); - Transaction transaction = session.beginTransaction(); - Quizz quizz = session.get( Quizz.class, 1 ); - quizz.addQuestion( 1, new Question( 4, "question that should be at index 1" ) ); - transaction.commit(); - session.close(); - - session = openSession(); - transaction = session.beginTransaction(); - quizz = session.get( Quizz.class, 1); - assertEquals( 4, quizz.getQuestions().size() ); - assertEquals( 4, quizz.getQuestions().get( 1 ).getId().longValue() ); - transaction.commit(); - session.close(); - } - - @Test - public void addQuestionToDetachedQuizz() { - Session session = openSession(); - session.beginTransaction(); - Quizz quizz = session.get( Quizz.class, 1 ); - session.getTransaction().commit(); - session.close(); - - assertFalse( ( (PersistentCollection) quizz.getQuestions() ).wasInitialized() ); - - try { - // this is the crux of the comment on HHH-9195 in regard to uninitialized, detached collections and - // not allowing additions - quizz.addQuestion( new Question( 4, "question 4" ) ); - - // indexed-addition should fail - quizz.addQuestion( 1, new Question( 5, "question that should be at index 1" ) ); - fail( "Expecting a failure" ); - } - catch (LazyInitializationException ignore) { - // expected - } - -// session = openSession(); -// session.beginTransaction(); -// session.merge( quizz ); -// session.getTransaction().commit(); -// session.close(); -// -// session = openSession(); -// session.getTransaction().begin(); -// quizz = session.get( Quizz.class, 1); -// assertEquals( 5, quizz.getQuestions().size() ); -// assertEquals( 5, quizz.getQuestions().get( 1 ).getId().longValue() ); -// session.getTransaction().commit(); -// session.close(); - } - - /** - * This test succeeds thanks to a dirty workaround consisting in initializing the ordered question list after the - * question has been inserted - */ - @Test - public void addQuestionWithIndexAndInitializeTheListShouldAddQuestionAtSpecifiedIndex() { - Session session = openSession(); - Transaction transaction = session.beginTransaction(); - - Quizz quizz = session.get( Quizz.class, 1 ); - quizz.addQuestionAndInitializeLazyList( 1, new Question( 4, "question that should be at index 1" ) ); - - transaction.commit(); - session.close(); - - session = openSession(); - transaction = session.beginTransaction(); - - quizz = session.get( Quizz.class, 1 ); - - assertEquals( 4, quizz.getQuestions().size()); - assertEquals( 4, quizz.getQuestions().get(1).getId().longValue() ); - - transaction.commit(); - session.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-10375") - public void testAddQuestionAfterSessionIsClosed(){ - Session session = openSession(); - Transaction transaction = session.beginTransaction(); - - Quizz quizz = session.get( Quizz.class, 1 ); - assertThat( "expected 3 questions", quizz.getQuestions().size(), is(3) ); - transaction.commit(); - session.close(); - - quizz.addQuestion( new Question( 4, "question 4" ) ); - assertThat( "expected 4 questions", quizz.getQuestions().size(), is(4) ); - - quizz.addQuestion( 1, new Question( 5, "question 5" ) ); - assertThat( "expected 5 questions", quizz.getQuestions().size(), is(5) ); - } - - - @Entity( name = "Question" ) - @Table( name = "Question" ) - public static class Question { - @Id - private Integer id; - private String text; - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - private Quizz quizz; - - public Question() { - } - - public Question(Integer id, String text) { - this.id = id; - this.text = text; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public Quizz getQuizz() { - return quizz; - } - - public void setQuizz(Quizz quizz) { - this.quizz = quizz; - } - - @Override - public String toString() { - return "Question{" + - "id=" + id + - ", text='" + text + '\'' + - '}'; - } - } - - @Entity( name = "Quizz" ) - @Table( name = "Quiz" ) - public static class Quizz { - @Id - private Integer id; - - @OneToMany(mappedBy = "quizz", cascade = CascadeType.ALL, orphanRemoval = true) - @OrderColumn(name = "position") - private List questions = new ArrayList(); - - public Quizz() { - } - - public Quizz(Integer id) { - this.id = id; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public List getQuestions() { - return questions; - } - - public void addQuestion(Question question) { - question.setQuizz(this); - questions.add(question); - } - - public void addQuestion(int index, Question question) { - question.setQuizz(this); - questions.add(index, question); - } - - public void addQuestionAndInitializeLazyList(int index, Question question) { - question.setQuizz(this); - questions.add(index, question); - Hibernate.initialize( questions ); - } - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListDelayedOperationTest.java deleted file mode 100644 index ff768dd5da..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/ListDelayedOperationTest.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ - -package org.hibernate.test.collection.delayedOperation; - -import java.util.ArrayList; -import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderColumn; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; -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.assertTrue; - -/** - * Tests delayed operations that are queued for a PersistentSet. remove( Object ) - * requires extra lazy to queue the operations. - * @author Gail Badner - */ -public class ListDelayedOperationTest extends BaseCoreFunctionalTestCase { - private Long parentId; - private Long childId1; - private Long childId2; - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } - - @Before - public void setup() { - // start by cleaning up in case a test fails - if ( parentId != null ) { - cleanup(); - } - - Parent parent = new Parent(); - Child child1 = new Child( "Sherman" ); - Child child2 = new Child( "Yogi" ); - parent.addChild( child1 ); - parent.addChild( child2 ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = parent.getId(); - childId1 = child1.getId(); - childId2 = child2.getId(); - } - - @After - public void cleanup() { - Session s = openSession(); - s.getTransaction().begin(); - Parent parent = s.get( Parent.class, parentId ); - parent.getChildren().clear(); - s.delete( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = null; - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddDetached() { - // Create 2 detached Child objects. - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Now Child c is detached. - - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add detached Child c - p.addChild( c1 ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - // Add a detached Child and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another detached Child, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p.addChild( c2 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddTransient() { - // Add a transient Child and commit. - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Darwin" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another transient Child and commit again. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Comet" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddManaged() { - // Add 2 Child entities - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Add a managed Child and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the first Child so it is managed; add to collection - p.addChild( s.get( Child.class, c1.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add the other managed Child, merge and commit. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the second Child so it is managed; add to collection - p.addChild( s.get( Child.class, c2.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleRemoveDetached() { - // Get the 2 Child entities and detach. - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = s.get( Child.class, childId1 ); - Child c2 = s.get( Child.class, childId2 ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // remove a detached element and commit - Hibernate.initialize( p.getChildren() ); - p.removeChild( c1 ); - for ( Child c : p.getChildren() ) { - if ( c.equals( c1 ) ) { - s.evict( c ); - } - } - assertTrue( Hibernate.isInitialized( p.getChildren() ) ); - //s.merge( p ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - Hibernate.initialize( p.getChildren() ); - assertEquals( 1, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // remove a detached element and commit - p.removeChild( c2 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p = (Parent) s.merge( p ); - Hibernate.initialize( p ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 0, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - -/* STILL WORKING ON THIS ONE... - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleRemoveManaged() { - // Remove a managed entity element and commit - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get c1 so it is managed, then remove and commit - p.removeChild( s.get( Child.class, childId1 ) ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 1, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get c1 so it is managed, then remove, merge and commit - p.removeChild( s.get( Child.class, childId2 ) ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 0, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } -*/ - - @Entity(name = "Parent") - public static class Parent { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) - @LazyCollection(LazyCollectionOption.EXTRA ) - @OrderColumn - private List children = new ArrayList(); - - public Parent() { - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public List getChildren() { - return children; - } - - public void addChild(Child child) { - children.add(child); - child.setParent(this); - } - - public void addChild(Child child, int i) { - children.add(i, child ); - child.setParent(this); - } - - public void removeChild(Child child) { - children.remove(child); - child.setParent(null); - } - } - - @Entity(name = "Child") - public static class Child { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false) - private String name; - - @ManyToOne - private Parent parent; - - public Child() { - } - - public Child(String name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - - @Override - public String toString() { - return "Child{" + - "id=" + id + - ", name='" + name + '\'' + - '}'; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - Child child = (Child) o; - - return name.equals( child.name ); - - } - - @Override - public int hashCode() { - return name.hashCode(); - } - } - -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/SetDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/SetDelayedOperationTest.java deleted file mode 100644 index 4c7dbe5644..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/SetDelayedOperationTest.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ - -package org.hibernate.test.collection.delayedOperation; - -import java.util.HashSet; -import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * Tests delayed operations that are queued for a PersistentSet. The Set must be - * extra lazy to queue the operations. - * @author Gail Badner - */ -public class SetDelayedOperationTest extends BaseCoreFunctionalTestCase { - private Long parentId; - private Long childId1; - private Long childId2; - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Parent.class, - Child.class - }; - } - - @Before - public void setup() { - // start by cleaning up in case a test fails - if ( parentId != null ) { - cleanup(); - } - - Parent parent = new Parent(); - Child child1 = new Child( "Sherman" ); - Child child2 = new Child( "Yogi" ); - parent.addChild( child1 ); - parent.addChild( child2 ); - - Session s = openSession(); - s.getTransaction().begin(); - s.persist( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = parent.getId(); - childId1 = child1.getId(); - childId2 = child2.getId(); - } - - @After - public void cleanup() { - Session s = openSession(); - s.getTransaction().begin(); - Parent parent = s.get( Parent.class, parentId ); - parent.getChildren().clear(); - s.delete( parent ); - s.getTransaction().commit(); - s.close(); - - parentId = null; - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddDetached() { - // Create 2 detached Child objects. - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Now Child c is detached. - - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add detached Child c - p.addChild( c1 ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - // Add a detached Child and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another detached Child, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p.addChild( c2 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddTransient() { - // Add a transient Child and commit. - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Darwin" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add another transient Child and commit again. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // add transient Child - p.addChild( new Child( "Comet" ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleAddManaged() { - // Add 2 Child entities - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = new Child( "Darwin" ); - s.persist( c1 ); - Child c2 = new Child( "Comet" ); - s.persist( c2 ); - s.getTransaction().commit(); - s.close(); - - // Add a managed Child and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the first Child so it is managed; add to collection - p.addChild( s.get( Child.class, c1.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 3, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Add the other managed Child, merge and commit. - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get the second Child so it is managed; add to collection - p.addChild( s.get( Child.class, c2.getId() ) ); - // collection should still be uninitialized - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 4, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleRemoveDetached() { - // Get the 2 Child entities and detach. - Session s = openSession(); - s.getTransaction().begin(); - Child c1 = s.get( Child.class, childId1 ); - Child c2 = s.get( Child.class, childId2 ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element and commit - s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // remove a detached element and commit - p.removeChild( c1 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 1, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // remove a detached element and commit - p.removeChild( c2 ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - p = (Parent) s.merge( p ); - Hibernate.initialize( p ); - s.getTransaction().commit(); - s.close(); - - // Remove a detached entity element, merge, and commit - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 0, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Test - @TestForIssue( jiraKey = "HHH-5855") - public void testSimpleRemoveManaged() { - // Remove a managed entity element and commit - Session s = openSession(); - s.getTransaction().begin(); - Parent p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get c1 so it is managed, then remove and commit - p.removeChild( s.get( Child.class, childId1 ) ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 1, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - // get c1 so it is managed, then remove, merge and commit - p.removeChild( s.get( Child.class, childId2 ) ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - s.merge( p ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.getTransaction().begin(); - p = s.get( Parent.class, parentId ); - assertFalse( Hibernate.isInitialized( p.getChildren() ) ); - assertEquals( 0, p.getChildren().size() ); - s.getTransaction().commit(); - s.close(); - } - - @Entity(name = "Parent") - public static class Parent { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true) - @LazyCollection( value = LazyCollectionOption.EXTRA) - private Set children = new HashSet(); - - public Parent() { - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Set getChildren() { - return children; - } - - public void addChild(Child child) { - children.add(child); - child.setParent(this); - } - - public void removeChild(Child child) { - children.remove(child); - child.setParent(null); - } - } - - @Entity(name = "Child") - public static class Child { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false) - private String name; - - @ManyToOne - private Parent parent; - - public Child() { - } - - public Child(String name) { - this.name = name; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - - @Override - public String toString() { - return "Child{" + - "id=" + id + - ", name='" + name + '\'' + - '}'; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - Child child = (Child) o; - - return name.equals( child.name ); - - } - - @Override - public int hashCode() { - return name.hashCode(); - } - } - -}