/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.immutable.entitywithmutablecollection;
import org.hibernate.QueryException;
import org.hibernate.Session;
import org.hibernate.StaleObjectStateException;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.internal.SessionFactoryImpl;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Gail Badner
*/
@SuppressWarnings( {"UnusedDeclaration"})
public abstract class AbstractEntityWithOneToManyTest extends BaseCoreFunctionalTestCase {
private boolean isContractPartiesInverse;
private boolean isContractPartiesBidirectional;
private boolean isContractVariationsBidirectional;
private boolean isContractVersioned;
public void configure(Configuration cfg) {
cfg.setProperty( Environment.GENERATE_STATISTICS, "true");
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
}
protected boolean checkUpdateCountsAfterAddingExistingElement() {
return true;
}
protected boolean checkUpdateCountsAfterRemovingElementWithoutDelete() {
return true;
}
protected void prepareTest() throws Exception {
super.prepareTest();
isContractPartiesInverse = ( ( SessionFactoryImpl ) sessionFactory() ).getCollectionPersister( Contract.class.getName() + ".parties" ).isInverse();
try {
( ( SessionFactoryImpl ) sessionFactory() ).getEntityPersister( Party.class.getName() ).getPropertyType( "contract" );
isContractPartiesBidirectional = true;
}
catch ( QueryException ex) {
isContractPartiesBidirectional = false;
}
try {
( ( SessionFactoryImpl ) sessionFactory() ).getEntityPersister( ContractVariation.class.getName() ).getPropertyType( "contract" );
isContractVariationsBidirectional = true;
}
catch ( QueryException ex) {
isContractVariationsBidirectional = false;
}
isContractVersioned = ( ( SessionFactoryImpl ) sessionFactory() ).getEntityPersister( Contract.class.getName() ).isVersioned();
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testUpdateProperty() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
c.addParty( new Party( "party" ) );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
c.setCustomerName( "yogi" );
assertEquals( 1, c.getParties().size() );
Party party = ( Party ) c.getParties().iterator().next();
party.setName( "new party" );
t.commit();
s.close();
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testCreateWithNonEmptyOneToManyCollectionOfNew() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
c.addParty( new Party( "party" ) );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 1, c.getParties().size() );
Party party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testCreateWithNonEmptyOneToManyCollectionOfExisting() {
clearCounts();
Party party = new Party( "party" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( party );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( 0 );
clearCounts();
Contract c = new Contract( null, "gail", "phone");
c.addParty( party );
s = openSession();
t = s.beginTransaction();
s.save( c );
t.commit();
s.close();
assertInsertCount( 1 );
// BUG, should be assertUpdateCount( ! isContractPartiesInverse && isPartyVersioned ? 1 : 0 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 0 , c.getParties().size() );
party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
assertNull( party.getContract() );
s.delete( party );
}
else {
assertEquals( 1 , c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testAddNewOneToManyElementToPersistentEntity() {
clearCounts();
Contract c = new Contract( null, "gail", "phone" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.get( Contract.class, c.getId() );
assertEquals( 0, c.getParties().size() );
c.addParty( new Party( "party" ) );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 1, c.getParties().size() );
Party party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testAddExistingOneToManyElementToPersistentEntity() {
clearCounts();
Contract c = new Contract( null, "gail", "phone" );
Party party = new Party( "party" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
s.persist( party );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.get( Contract.class, c.getId() );
assertEquals( 0, c.getParties().size() );
party = ( Party ) s.get( Party.class, party.getId() );
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
c.addParty( party );
t.commit();
s.close();
assertInsertCount( 0 );
if ( checkUpdateCountsAfterAddingExistingElement() ) {
assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
}
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 0, c.getParties().size() );
s.delete( party );
}
else {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testCreateWithEmptyOneToManyCollectionUpdateWithExistingElement() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
s.persist( party );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.addParty( party );
s = openSession();
t = s.beginTransaction();
s.update( c );
t.commit();
s.close();
assertInsertCount( 0 );
if ( checkUpdateCountsAfterAddingExistingElement() ) {
assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
}
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 0, c.getParties().size() );
s.delete( party );
}
else {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testCreateWithNonEmptyOneToManyCollectionUpdateWithNewElement() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
Party newParty = new Party( "new party" );
c.addParty( newParty );
s = openSession();
t = s.beginTransaction();
s.update( c );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
assertEquals( 2, c.getParties().size() );
for ( Object o : c.getParties() ) {
Party aParty = (Party) o;
if ( aParty.getId() == party.getId() ) {
assertEquals( "party", aParty.getName() );
}
else if ( aParty.getId() == newParty.getId() ) {
assertEquals( "new party", aParty.getName() );
}
else {
fail( "unknown party" );
}
if ( isContractPartiesBidirectional ) {
assertSame( c, aParty.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 3 );
}
@Test
@SuppressWarnings( {"UnusedAssignment", "UnnecessaryBoxing"})
public void testCreateWithEmptyOneToManyCollectionMergeWithExistingElement() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
s.persist( party );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.addParty( party );
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.merge( c );
t.commit();
s.close();
assertInsertCount( 0 );
if ( checkUpdateCountsAfterAddingExistingElement() ) {
assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
}
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 0, c.getParties().size() );
s.delete( party );
}
else {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnusedAssignment", "UnnecessaryBoxing"})
public void testCreateWithNonEmptyOneToManyCollectionMergeWithNewElement() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
Party newParty = new Party( "new party" );
c.addParty( newParty );
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.merge( c );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
assertEquals( 2, c.getParties().size() );
for ( Object o : c.getParties() ) {
Party aParty = (Party) o;
if ( aParty.getId() == party.getId() ) {
assertEquals( "party", aParty.getName() );
}
else if ( !aParty.getName().equals( newParty.getName() ) ) {
fail( "unknown party:" + aParty.getName() );
}
if ( isContractPartiesBidirectional ) {
assertSame( c, aParty.getContract() );
}
}
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 3 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testMoveOneToManyElementToNewEntityCollection() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
c.addParty( new Party( "party" ) );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 1, c.getParties().size() );
Party party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
c.removeParty( party );
Contract c2 = new Contract(null, "david", "phone" );
c2.addParty( party );
s.save( c2 );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c.getId() ) )).uniqueResult();
c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c2.getId() ) )).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
assertEquals( 0, c2.getParties().size() );
}
else {
assertEquals( 0, c.getParties().size() );
assertEquals( 1, c2.getParties().size() );
party = ( Party ) c2.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c2, party.getContract() );
}
}
s.delete(c);
s.delete( c2 );
assertEquals( new Long( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( new Long( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 3 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testMoveOneToManyElementToExistingEntityCollection() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
c.addParty( new Party( "party" ) );
Contract c2 = new Contract(null, "david", "phone" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
s.persist( c2 );
t.commit();
s.close();
assertInsertCount( 3 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c.getId() ) )).uniqueResult();
assertEquals( 1, c.getParties().size() );
Party party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
c.removeParty( party );
c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c2.getId() ) )).uniqueResult();
c2.addParty( party );
t.commit();
s.close();
assertInsertCount( 0 );
assertUpdateCount( isContractVersioned ? 2 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c.getId() ) )).uniqueResult();
c2 = (Contract) s.createCriteria( Contract.class ).add( Restrictions.idEq( Long.valueOf( c2.getId() ) )).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c, party.getContract() );
}
assertEquals( 0, c2.getParties().size() );
}
else {
assertEquals( 0, c.getParties().size() );
assertEquals( 1, c2.getParties().size() );
party = ( Party ) c2.getParties().iterator().next();
assertEquals( "party", party.getName() );
if ( isContractPartiesBidirectional ) {
assertSame( c2, party.getContract() );
}
}
s.delete(c);
s.delete( c2 );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Contract.class ).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria( Party.class ).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 3 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testRemoveOneToManyElementUsingUpdate() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.removeParty( party );
assertEquals( 0, c.getParties().size() );
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
s = openSession();
t = s.beginTransaction();
s.update( c );
s.update( party );
t.commit();
s.close();
if ( checkUpdateCountsAfterRemovingElementWithoutDelete() ) {
assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
}
assertDeleteCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
assertSame( c, party.getContract() );
}
else {
assertEquals( 0, c.getParties().size() );
party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
s.delete( party );
}
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnusedAssignment", "UnnecessaryBoxing"})
public void testRemoveOneToManyElementUsingMerge() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.removeParty( party );
assertEquals( 0, c.getParties().size() );
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.merge( c );
party = ( Party ) s.merge( party );
t.commit();
s.close();
if ( checkUpdateCountsAfterRemovingElementWithoutDelete() ) {
assertUpdateCount( isContractVersioned && ! isContractPartiesInverse ? 1 : 0 );
}
assertDeleteCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
if ( isContractPartiesInverse ) {
assertEquals( 1, c.getParties().size() );
party = ( Party ) c.getParties().iterator().next();
assertEquals( "party", party.getName() );
assertSame( c, party.getContract() );
}
else {
assertEquals( 0, c.getParties().size() );
party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
s.delete( party );
}
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testDeleteOneToManyElement() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
s.update( c );
c.removeParty( party );
s.delete( party );
t.commit();
s.close();
assertUpdateCount( isContractVersioned ? 1 : 0 );
assertDeleteCount( 1 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 0, c.getParties().size() );
party = ( Party ) s.createCriteria( Party.class ).uniqueResult();
assertNull( party );
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 1 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testRemoveOneToManyElementByDelete() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
Party party = new Party( "party" );
c.addParty( party );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.removeParty( party );
assertEquals( 0, c.getParties().size() );
if ( isContractPartiesBidirectional ) {
assertNull( party.getContract() );
}
s = openSession();
t = s.beginTransaction();
s.update( c );
s.delete( party );
t.commit();
s.close();
assertUpdateCount( isContractVersioned ? 1 : 0 );
assertDeleteCount( 1 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 0, c.getParties().size() );
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 1 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testRemoveOneToManyOrphanUsingUpdate() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
ContractVariation cv = new ContractVariation( 1, c );
cv.setText( "cv1" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.getVariations().remove( cv );
cv.setContract( null );
assertEquals( 0, c.getVariations().size() );
if ( isContractVariationsBidirectional ) {
assertNull( cv.getContract() );
}
s = openSession();
t = s.beginTransaction();
s.update( c );
t.commit();
s.close();
assertUpdateCount( isContractVersioned ? 1 : 0 );
assertDeleteCount( 1 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 0, c.getVariations().size() );
cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
assertNull( cv );
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 1 );
}
@Test
@SuppressWarnings( {"UnusedAssignment", "UnnecessaryBoxing"})
public void testRemoveOneToManyOrphanUsingMerge() {
Contract c = new Contract( null, "gail", "phone");
ContractVariation cv = new ContractVariation( 1, c );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
c.getVariations().remove( cv );
cv.setContract( null );
assertEquals( 0, c.getVariations().size() );
if ( isContractVariationsBidirectional ) {
assertNull( cv.getContract() );
}
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.merge( c );
cv = ( ContractVariation ) s.merge( cv );
t.commit();
s.close();
assertUpdateCount( isContractVersioned ? 1 : 0 );
assertDeleteCount( 1 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 0, c.getVariations().size() );
cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
assertNull( cv );
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 1 );
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testDeleteOneToManyOrphan() {
clearCounts();
Contract c = new Contract( null, "gail", "phone");
ContractVariation cv = new ContractVariation( 1, c );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( c );
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
s.update( c );
c.getVariations().remove( cv );
cv.setContract( null );
assertEquals( 0, c.getVariations().size() );
s.delete( cv );
t.commit();
s.close();
assertUpdateCount( isContractVersioned ? 1 : 0 );
assertDeleteCount( 1 );
clearCounts();
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.createCriteria( Contract.class ).uniqueResult();
assertEquals( 0, c.getVariations().size() );
cv = ( ContractVariation ) s.createCriteria( ContractVariation.class ).uniqueResult();
assertNull( cv );
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 1 );
}
@SuppressWarnings( {"UnnecessaryBoxing"})
@Test
public void testOneToManyCollectionOptimisticLockingWithMerge() {
clearCounts();
Contract cOrig = new Contract( null, "gail", "phone");
Party partyOrig = new Party( "party" );
cOrig.addParty( partyOrig );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(cOrig);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
Contract c = ( Contract ) s.get( Contract.class, cOrig.getId() );
Party newParty = new Party( "new party" );
c.addParty( newParty );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
cOrig.removeParty( partyOrig );
try {
s.merge( cOrig );
assertFalse( isContractVersioned );
}
catch (StaleObjectStateException ex) {
assertTrue( isContractVersioned);
}
finally {
t.rollback();
}
s.close();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
s.delete(c);
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
assertUpdateCount( 0 );
assertDeleteCount( 3 );
}
@SuppressWarnings( {"UnnecessaryBoxing"})
@Test
public void testOneToManyCollectionOptimisticLockingWithUpdate() {
clearCounts();
Contract cOrig = new Contract( null, "gail", "phone");
Party partyOrig = new Party( "party" );
cOrig.addParty( partyOrig );
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(cOrig);
t.commit();
s.close();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
Contract c = ( Contract ) s.get( Contract.class, cOrig.getId() );
Party newParty = new Party( "new party" );
c.addParty( newParty );
t.commit();
s.close();
assertInsertCount( 1 );
assertUpdateCount( isContractVersioned ? 1 : 0 );
clearCounts();
s = openSession();
t = s.beginTransaction();
cOrig.removeParty( partyOrig );
s.update( cOrig );
try {
t.commit();
assertFalse( isContractVersioned );
}
catch (StaleObjectStateException ex) {
assertTrue( isContractVersioned);
t.rollback();
}
s.close();
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
s.createQuery( "delete from Party" ).executeUpdate();
s.delete( c );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult() );
assertEquals( Long.valueOf( 0 ), s.createCriteria(Party.class).setProjection( Projections.rowCount() ).uniqueResult() );
t.commit();
s.close();
}
protected void clearCounts() {
sessionFactory().getStatistics().clear();
}
protected void assertInsertCount(int expected) {
int inserts = ( int ) sessionFactory().getStatistics().getEntityInsertCount();
assertEquals( "unexpected insert count", expected, inserts );
}
protected void assertUpdateCount(int expected) {
int updates = ( int ) sessionFactory().getStatistics().getEntityUpdateCount();
assertEquals( "unexpected update counts", expected, updates );
}
protected void assertDeleteCount(int expected) {
int deletes = ( int ) sessionFactory().getStatistics().getEntityDeleteCount();
assertEquals( "unexpected delete counts", expected, deletes );
}
}