Re-enabled additional tests
This commit is contained in:
parent
23ffe42b6c
commit
dfb3511923
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.collection.basic;
|
||||
package org.hibernate.orm.test.collection.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.collection.basic;
|
||||
package org.hibernate.orm.test.collection.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.*;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
|
||||
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<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
|
||||
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() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.collection.basic;
|
||||
package org.hibernate.orm.test.collection.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Basic;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<String> childNames = new HashSet<String>(
|
||||
Arrays.asList( new String[] { "Yogi", "Sherman" } )
|
||||
final Set<String> 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<String> childNames = new HashSet<String>(
|
||||
Arrays.asList( new String[] { "Yogi", "Sherman", "Zeke" } )
|
||||
final Set<String> 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<Child> children ;
|
||||
private List<Child> 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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<Question> 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<Question> 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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new HashSet<>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Set<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
|
||||
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<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
|
||||
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() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<Question> questions = new ArrayList<Question>();
|
||||
|
||||
public Quizz() {
|
||||
}
|
||||
|
||||
public Quizz(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Question> 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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new ArrayList<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
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<Child> children = new HashSet<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Set<Child> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue