/*
* 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.ops;
import javax.persistence.PersistenceException;
import java.util.List;
import org.junit.Test;
import org.hibernate.Hibernate;
import org.hibernate.PersistentObjectException;
import org.hibernate.Session;
import org.hibernate.StaleObjectStateException;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Tests merging multiple detached representations of the same entity when explicitly allowed.
*
* @author Gail Badner
*/
public class MergeMultipleEntityCopiesAllowedTest extends BaseCoreFunctionalTestCase {
public String[] getMappings() {
return new String[] {
"ops/Hoarder.hbm.xml"
};
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty(
"hibernate.event.merge.entity_copy_observer",
"allow"
);
}
@Test
public void testNestedDiffBasicProperty() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// change basic property of nested entity
item1_1.setName( "item1_1 name" );
// change the nested Item to be the copy with the new name
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the name from the top level item will win.
assertEquals( item1.getName(), item1Merged.getName() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
Item item1Get = (Item) s.get( Item.class, item1.getId() );
assertEquals( item1.getName(), item1Get.getName() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testNestedManyToOneChangedToNull() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// change many-to-one in nested entity to null.
item1_1.setCategory( null );
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the many-to-one from the top level item will win.
assertEquals( category.getName(), item1Merged.getCategory().getName() );
assertSame( item1Merged, item1Merged.getCategory().getExampleItem() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( category.getName(), item1.getCategory().getName() );
assertSame( item1, item1.getCategory().getExampleItem() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testNestedManyToOneChangedToNewEntity() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// change many-to-one in nested entity to a new (transient) value
Category categoryNew = new Category();
categoryNew.setName( "new category" );
item1_1.setCategory( categoryNew );
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the many-to-one from the top level item will win.
assertEquals( category.getName(), item1Merged.getCategory().getName() );
assertSame( item1Merged, item1Merged.getCategory().getExampleItem() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( category.getName(), item1.getCategory().getName() );
assertSame( item1, item1.getCategory().getExampleItem() );
// make sure new category got persisted
Category categoryQueried = (Category) s.createQuery( "from Category c where c.name='new category'" ).uniqueResult();
assertNotNull( categoryQueried );
tx.commit();
s.close();
cleanup();
}
@Test
public void testTopLevelManyToOneChangedToNewEntity() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// change many-to-one in top level to be a new (transient)
Category categoryNewer = new Category();
categoryNewer.setName( "newer category" );
item1.setCategory( categoryNewer );
// put the other representation in categoryNewer
categoryNewer.setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the many-to-one from the top level item will win.
assertEquals( categoryNewer.getName(), item1Merged.getCategory().getName() );
assertSame( item1Merged, item1Merged.getCategory().getExampleItem() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( categoryNewer.getName(), item1.getCategory().getName() );
assertSame( item1, item1.getCategory().getExampleItem() );
// make sure original category is still there
Category categoryQueried = (Category) s.createQuery( "from Category c where c.name='category'" ).uniqueResult();
assertNotNull( categoryQueried );
// make sure original category has the same item.
assertSame( item1, categoryQueried.getExampleItem() );
// set exampleItem to null to avoid constraint violation on cleanup.
categoryQueried.setExampleItem( null );
tx.commit();
s.close();
cleanup();
}
@Test
public void testTopLevelManyToOneManagedNestedIsDetached() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
item1Merged.setCategory( category );
category.setExampleItem( item1_1 );
// now item1Merged is managed and it has a nested detached item
s.merge( item1Merged );
assertEquals( category.getName(), item1Merged.getCategory().getName() );
assertSame( item1Merged, item1Merged.getCategory().getExampleItem() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( category.getName(), item1.getCategory().getName() );
assertSame( item1, item1.getCategory().getExampleItem() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testNestedValueCollectionWithChangedElements() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.getColors().add( "red" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
Hibernate.initialize( item1_1.getColors() );
tx.commit();
s.close();
// add an element to collection in nested entity
item1_1.getColors().add( "blue" );
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the collection from the top level item will win.
assertEquals( 1, item1Merged.getColors().size() );
assertEquals( "red", item1Merged.getColors().iterator().next() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 1, item1.getColors().size() );
assertEquals( "red", item1.getColors().iterator().next() );
Hibernate.initialize( item1.getCategory() );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
item1_1 = (Item) s.get( Item.class, item1.getId() );
Hibernate.initialize( item1_1.getColors() );
tx.commit();
s.close();
// remove the existing elements from collection in nested entity
item1_1.getColors().clear();
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
item1Merged = (Item) s.merge( item1 );
// the collection from the top level item will win.
assertEquals( 1, item1Merged.getColors().size() );
assertEquals( "red", item1Merged.getColors().iterator().next() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 1, item1.getColors().size() );
assertEquals( "red", item1.getColors().iterator().next() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testTopValueCollectionWithChangedElements() {
Item item1 = new Item();
item1.setName( "item1 name" );
Category category = new Category();
category.setName( "category" );
item1.getColors().add( "red" );
item1.setCategory( category );
category.setExampleItem( item1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// add an element to collection in nested entity
item1.getColors().add( "blue" );
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// the collection from the top level item will win.
assertEquals( 2, item1Merged.getColors().size() );
assertTrue( item1Merged.getColors().contains( "red" ) );
assertTrue( item1Merged.getColors().contains( "blue" ) );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 2, item1.getColors().size() );
assertTrue( item1.getColors().contains( "red" ) );
assertTrue( item1.getColors().contains( "blue" ) );
Hibernate.initialize( item1.getCategory() );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
// remove the existing elements from collection in nested entity
item1.getColors().clear();
item1.getCategory().setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
item1Merged = (Item) s.merge( item1 );
// the collection from the top level item will win.
assertTrue( item1Merged.getColors().isEmpty() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertTrue( item1.getColors().isEmpty() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testCascadeFromTransientToNonDirtyRepresentations() {
Item item1 = new Item();
item1.setName( "item1" );
Session s = openSession();
Transaction tx = session.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// Get another representation of the same Item from a different session.
s = openSession();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
s.close();
// item1_1 and item1_2 are unmodified representations of the same persistent entity.
assertFalse( item1 == item1_1 );
assertTrue( item1.equals( item1_1 ) );
// Create a transient entity that references both representations.
Hoarder hoarder = new Hoarder();
hoarder.setName( "joe" );
hoarder.getItems().add( item1 );
hoarder.setFavoriteItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testCascadeFromDetachedToNonDirtyRepresentations() {
Item item1 = new Item();
item1.setName( "item1" );
Hoarder hoarder = new Hoarder();
hoarder.setName( "joe" );
Session s = openSession();
Transaction tx = session.beginTransaction();
s.persist( item1 );
s.persist( hoarder );
tx.commit();
s.close();
// Get another representation of the same Item from a different session.
s = openSession();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
s.close();
// item1_1 and item1_2 are unmodified representations of the same persistent entity.
assertFalse( item1 == item1_1 );
assertTrue( item1.equals( item1_1 ) );
// Update hoarder (detached) to references both representations.
hoarder.getItems().add( item1 );
hoarder.setFavoriteItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testCascadeFromDetachedToGT2DirtyRepresentations() {
Item item1 = new Item();
item1.setName( "item1" );
Category category1 = new Category();
category1.setName( "category1" );
item1.setCategory( category1 );
Hoarder hoarder = new Hoarder();
hoarder.setName( "joe" );
Session s = openSession();
Transaction tx = session.beginTransaction();
s.persist( item1 );
s.persist( hoarder );
tx.commit();
s.close();
// Get another representation of the same Item from a different session.
s = openSession();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
s.close();
// item1 and item1_1 are unmodified representations of the same persistent entity.
assertFalse( item1 == item1_1 );
assertTrue( item1.equals( item1_1 ) );
// Get another representation of the same Item from a different session.
s = openSession();
Item item1_2 = (Item) s.get( Item.class, item1.getId() );
s.close();
// item1_1 and item1_2 are unmodified representations of the same persistent entity.
assertFalse( item1 == item1_2 );
assertTrue( item1.equals( item1_2) );
item1_1.setName( "item1_1" );
item1_2.setName( "item1_2" );
// Update hoarder (detached) to references both representations.
item1.getCategory().setExampleItem( item1_2 );
hoarder.getItems().add( item1 );
hoarder.setFavoriteItem( item1_1 );
hoarder.getFavoriteItem().getCategory();
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertSame( hoarder.getFavoriteItem(), hoarder.getFavoriteItem().getCategory().getExampleItem() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
assertEquals( item1.getName(), hoarder.getFavoriteItem().getName() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
hoarder = (Hoarder) s.merge( hoarder );
assertEquals( 1, hoarder.getItems().size() );
assertSame( hoarder.getFavoriteItem(), hoarder.getItems().iterator().next() );
assertSame( hoarder.getFavoriteItem(), hoarder.getFavoriteItem().getCategory().getExampleItem() );
assertEquals( item1.getId(), hoarder.getFavoriteItem().getId() );
assertEquals( item1.getCategory(), hoarder.getFavoriteItem().getCategory() );
tx.commit();
s.close();
cleanup();
}
@Test
public void testTopLevelEntityNewerThanNested() {
Item item = new Item();
item.setName( "item" );
Category category = new Category();
category.setName( "category" );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item );
s.persist( category );
tx.commit();
s.close();
// Get the Category from a different session.
s = openSession();
tx = s.beginTransaction();
Category category1_2 = (Category) s.get( Category.class, category.getId() );
tx.commit();
s.close();
// Get and update the same Category.
s = openSession();
tx = s.beginTransaction();
Category category1_1 = (Category) s.get( Category.class, category.getId() );
category1_1.setName( "new name" );
tx.commit();
s.close();
assertTrue( category1_2.getVersion() < category1_1.getVersion() );
category1_1.setExampleItem( item );
item.setCategory( category1_2 );
s = openSession();
tx = s.beginTransaction();
try {
// representation merged at top level is newer than nested representation.
category1_1 = (Category) s.merge( category1_1 );
fail( "should have failed because one representation is an older version." );
}
catch (PersistenceException e){
// expected
assertTyping( StaleObjectStateException.class, e.getCause());
}
finally {
tx.rollback();
s.close();
}
cleanup();
}
@Test
public void testNestedEntityNewerThanTopLevel() {
Item item = new Item();
item.setName( "item" );
Category category = new Category();
category.setName( "category" );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item );
s.persist( category );
tx.commit();
s.close();
// Get category1_1 from a different session.
s = openSession();
Category category1_1 = (Category) s.get( Category.class, category.getId() );
s.close();
// Get and update category1_2 to increment its version.
s = openSession();
tx = s.beginTransaction();
Category category1_2 = (Category) s.get( Category.class, category.getId() );
category1_2.setName( "new name" );
tx.commit();
s.close();
assertTrue( category1_2.getVersion() > category1_1.getVersion() );
category1_1.setExampleItem( item );
item.setCategory( category1_2 );
s = openSession();
tx = s.beginTransaction();
try {
// nested representation is newer than top lever representation.
category1_1 = (Category) s.merge( category1_1 );
fail( "should have failed because one representation is an older version." );
}
catch (PersistenceException e){
// expected
assertTyping( StaleObjectStateException.class, e.getCause());
}
finally {
tx.rollback();
s.close();
}
cleanup();
}
@Test
@FailureExpected( jiraKey = "HHH-9240" )
public void testTopLevelUnidirOneToManyBackrefWithNewElement() {
Item item1 = new Item();
item1.setName( "item1 name" );
SubItem subItem1 = new SubItem();
subItem1.setName( "subItem1 name" );
item1.getSubItemsBackref().add( subItem1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
assertFalse( Hibernate.isInitialized( item1_1.getSubItemsBackref() ) );
Category category = new Category();
category.setName( "category" );
SubItem subItem2 = new SubItem();
subItem2.setName( "subItem2 name" );
item1.getSubItemsBackref().add( subItem2 );
item1.setCategory( category );
category.setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
// The following will fail due to PropertyValueException because item1 will
// be removed from the inverted merge map when the operation cascades to item1_1.
Item item1Merged = (Item) s.merge( item1 );
// top-level collection should win
assertEquals( 2, item1.getSubItemsBackref().size() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 2, item1.getSubItemsBackref().size() );
tx.commit();
s.close();
cleanup();
}
@Test
@FailureExpected( jiraKey = "HHH-9239" )
public void testNestedUnidirOneToManyBackrefWithNewElement() {
Item item1 = new Item();
item1.setName( "item1 name" );
SubItem subItem1 = new SubItem();
subItem1.setName( "subItem1 name" );
item1.getSubItemsBackref().add( subItem1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
Hibernate.initialize( item1_1.getSubItemsBackref() );
tx.commit();
s.close();
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
SubItem subItem2 = new SubItem();
subItem2.setName( "subItem2 name" );
item1_1.getSubItemsBackref().add( subItem2 );
category.setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// The resulting collection should contain the added element
assertEquals( 2, item1Merged.getSubItemsBackref().size() );
assertEquals( "subItem1 name", item1Merged.getSubItemsBackref().get( 0 ).getName() );
assertEquals( "subItem2 name", item1Merged.getSubItemsBackref().get( 1 ).getName() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 2, item1.getSubItemsBackref().size() );
assertEquals( "subItem1 name", item1.getSubItemsBackref().get( 0 ).getName() );
assertEquals( "subItem2 name", item1Merged.getSubItemsBackref().get( 1 ).getName() );
tx.commit();
s.close();
cleanup();
}
@Test
//@FailureExpected( jiraKey = "HHH-9106" )
public void testTopLevelUnidirOneToManyBackrefWithRemovedElement() {
Item item1 = new Item();
item1.setName( "item1 name" );
SubItem subItem1 = new SubItem();
subItem1.setName( "subItem1 name" );
item1.getSubItemsBackref().add( subItem1 );
SubItem subItem2 = new SubItem();
subItem2.setName( "subItem2 name" );
item1.getSubItemsBackref().add( subItem2 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
tx.commit();
s.close();
assertFalse( Hibernate.isInitialized( item1_1.getSubItemsBackref() ) );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1_1 );
// remove subItem1 from top-level Item
item1.getSubItemsBackref().remove( subItem1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// entity should have been removed
assertEquals( 1, item1Merged.getSubItemsBackref().size() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 1, item1.getSubItemsBackref().size() );
subItem1 = (SubItem) s.get( SubItem.class, subItem1.getId() );
// cascade does not include delete-orphan, so subItem1 should still be persistent.
assertNotNull( subItem1 );
tx.commit();
cleanup();
}
@Test
@FailureExpected( jiraKey = "HHH-9239" )
public void testNestedUnidirOneToManyBackrefWithRemovedElement() {
Item item1 = new Item();
item1.setName( "item1 name" );
SubItem subItem1 = new SubItem();
subItem1.setName( "subItem1 name" );
item1.getSubItemsBackref().add( subItem1 );
SubItem subItem2 = new SubItem();
subItem2.setName( "subItem2 name" );
item1.getSubItemsBackref().add( subItem2 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( item1 );
tx.commit();
s.close();
// get another representation of item1
s = openSession();
tx = s.beginTransaction();
Item item1_1 = (Item) s.get( Item.class, item1.getId() );
Hibernate.initialize( item1_1.getSubItemsBackref() );
tx.commit();
s.close();
// remove subItem1 from the nested Item
item1_1.getSubItemsBackref().remove( subItem1 );
Category category = new Category();
category.setName( "category" );
item1.setCategory( category );
category.setExampleItem( item1_1 );
s = openSession();
tx = s.beginTransaction();
Item item1Merged = (Item) s.merge( item1 );
// entity should have been removed
assertEquals( 1, item1Merged.getSubItemsBackref().size() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
item1 = (Item) s.get( Item.class, item1.getId() );
assertEquals( 1, item1.getSubItemsBackref().size() );
subItem1 = (SubItem) s.get( SubItem.class, subItem1.getId() );
// cascade does not include delete-orphan, so subItem1 should still be persistent.
assertNotNull( subItem1 );
tx.commit();
cleanup();
}
@Test
//@FailureExpected( jiraKey = "HHH-9106" )
public void testTopLevelUnidirOneToManyNoBackrefWithNewElement() {
Category category1 = new Category();
category1.setName( "category1 name" );
SubCategory subCategory1 = new SubCategory();
subCategory1.setName( "subCategory1 name" );
category1.getSubCategories().add( subCategory1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( category1 );
tx.commit();
s.close();
// get another representation of category1
s = openSession();
tx = s.beginTransaction();
Category category1_1 = (Category) s.get( Category.class, category1.getId() );
tx.commit();
s.close();
assertFalse( Hibernate.isInitialized( category1_1.getSubCategories() ) );
SubCategory subCategory2 = new SubCategory();
subCategory2.setName( "subCategory2 name" );
category1.getSubCategories().add( subCategory2 );
Item item = new Item();
item.setName( "item" );
category1.setExampleItem( item );
item.setCategory( category1_1 );
s = openSession();
tx = s.beginTransaction();
Category category1Merged = (Category) s.merge( category1 );
assertEquals( 2, category1Merged.getSubCategories().size() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
category1 = (Category) s.get( Category.class, category1.getId() );
assertEquals( 2, category1.getSubCategories().size() );
tx.commit();
s.close();
cleanup();
}
@Test
@FailureExpected( jiraKey = "HHH-9239" )
public void testNestedUnidirOneToManyNoBackrefWithNewElement() {
Category category1 = new Category();
category1.setName( "category1 name" );
SubCategory subCategory1 = new SubCategory();
subCategory1.setName( "subCategory1 name" );
category1.getSubCategories().add( subCategory1 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( category1 );
tx.commit();
s.close();
// get another representation of category1
s = openSession();
tx = s.beginTransaction();
Category category1_1 = (Category) s.get( Category.class, category1.getId() );
Hibernate.initialize( category1_1.getSubCategories() );
tx.commit();
s.close();
SubCategory subCategory2 = new SubCategory();
subCategory2.setName( "subCategory2 name" );
category1_1.getSubCategories().add( subCategory2 );
Item item = new Item();
item.setName( "item" );
category1.setExampleItem( item );
item.setCategory( category1_1 );
s = openSession();
tx = s.beginTransaction();
Category category1Merged = (Category) s.merge( category1 );
assertEquals( 2, category1Merged.getSubCategories().size() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
category1 = (Category) s.get( Category.class, category1.getId() );
assertEquals( 2, category1.getSubCategories().size() );
tx.commit();
s.close();
cleanup();
}
@Test
//@FailureExpected( jiraKey = "HHH-9106" )
public void testTopLevelUnidirOneToManyNoBackrefWithRemovedElement() {
Category category1 = new Category();
category1.setName( "category1 name" );
SubCategory subCategory1 = new SubCategory();
subCategory1.setName( "subCategory1 name" );
category1.getSubCategories().add( subCategory1 );
SubCategory subCategory2 = new SubCategory();
subCategory2.setName( "subCategory2 name" );
category1.getSubCategories().add( subCategory2 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( category1 );
tx.commit();
s.close();
// get another representation of category1
s = openSession();
tx = s.beginTransaction();
Category category1_1 = (Category) s.get( Category.class, category1.getId() );
tx.commit();
s.close();
assertFalse( Hibernate.isInitialized( category1_1.getSubCategories() ) );
Item item = new Item();
item.setName( "item" );
category1.setExampleItem( item );
item.setCategory( category1_1 );
category1.getSubCategories().remove( subCategory1 );
s = openSession();
tx = s.beginTransaction();
Category category1Merged = (Category) s.merge( category1 );
assertEquals( 1, category1Merged.getSubCategories().size() );
assertTrue( category1Merged.getSubCategories().contains( subCategory2 ) );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
category1 = (Category) s.get( Category.class, category1.getId() );
assertEquals( 1, category1.getSubCategories().size() );
assertTrue( category1.getSubCategories().contains( subCategory2 ) );
// cascade does not include delete-orphan, so subCategory1 should still be persistent.
subCategory1 = (SubCategory) s.get( SubCategory.class, subCategory1.getId() );
assertNotNull( subCategory1 );
tx.commit();
s.close();
cleanup();
}
@Test
@FailureExpected( jiraKey = "HHH-9239" )
public void testNestedUnidirOneToManyNoBackrefWithRemovedElement() {
Category category1 = new Category();
category1.setName( "category1 name" );
SubCategory subCategory1 = new SubCategory();
subCategory1.setName( "subCategory1 name" );
category1.getSubCategories().add( subCategory1 );
SubCategory subCategory2 = new SubCategory();
subCategory2.setName( "subCategory2 name" );
category1.getSubCategories().add( subCategory2 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( category1 );
tx.commit();
s.close();
// get another representation of category1
s = openSession();
tx = s.beginTransaction();
Category category1_1 = (Category) s.get( Category.class, category1.getId() );
Hibernate.initialize( category1_1.getSubCategories() );
tx.commit();
s.close();
category1_1.getSubCategories().remove( subCategory2 );
Item item = new Item();
item.setName( "item" );
category1.setExampleItem( item );
item.setCategory( category1_1 );
s = openSession();
tx = s.beginTransaction();
Category category1Merged = (Category) s.merge( category1 );
assertEquals( 1, category1Merged.getSubCategories().size() );
assertTrue( category1Merged.getSubCategories().contains( subCategory2 ) );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
category1 = (Category) s.get( Category.class, category1.getId() );
assertEquals( 1, category1.getSubCategories().size() );
assertTrue( category1.getSubCategories().contains( subCategory2 ) );
// cascade does not include delete-orphan, so subCategory1 should still be persistent.
subCategory1 = (SubCategory) s.get( SubCategory.class, subCategory1.getId() );
assertNotNull( subCategory1 );
tx.commit();
s.close();
cleanup();
}
@SuppressWarnings( {"unchecked"})
private void cleanup() {
Session s = openSession();
s.beginTransaction();
s.createQuery( "delete from SubItem" ).executeUpdate();
for ( Hoarder hoarder : (List<Hoarder>) s.createQuery( "from Hoarder" ).list() ) {
hoarder.getItems().clear();
s.delete( hoarder );
}
for ( Category category : (List<Category>) s.createQuery( "from Category" ).list() ) {
Item exampleItem = category.getExampleItem();
if ( exampleItem != null ) {
category.setExampleItem( null );
exampleItem.setCategory( null );
s.delete( category );
s.delete (exampleItem );
}
}
for ( Item item : (List<Item>) s.createQuery( "from Item" ).list() ) {
Category category = item.getCategory();
item.setCategory( null );
if ( category != null ) {
category.setExampleItem( null );
}
s.delete( item );
}
s.createQuery( "delete from Item" ).executeUpdate();
s.getTransaction().commit();
s.close();
}
}