/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* 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.ogm.backendtck.associations.collection.manytomany;
import static org.fest.assertions.Assertions.assertThat;
import static org.hibernate.ogm.utils.GridDialectType.NEO4J_EMBEDDED;
import static org.hibernate.ogm.utils.GridDialectType.NEO4J_REMOTE;
import static org.hibernate.ogm.utils.TestHelper.get;
import static org.hibernate.ogm.utils.TestHelper.getNumberOfAssociations;
import static org.hibernate.ogm.utils.TestHelper.getNumberOfEntities;
import java.util.EnumSet;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.ogm.utils.OgmTestCase;
import org.hibernate.ogm.utils.TestHelper;
import org.junit.Test;
/**
* @author Emmanuel Bernard <emmanuel@hibernate.org>
*/
public class ManyToManyTest extends OgmTestCase {
@Test
public void testBidirectionalManyToMany() {
Session session = openSession();
Transaction tx = session.beginTransaction();
AccountOwner owner = new AccountOwner( "owner_1" );
owner.setSSN( "0123456" );
BankAccount soge = new BankAccount( "account_1" );
soge.setAccountNumber( "X2345000" );
owner.getBankAccounts().add( soge );
soge.getOwners().add( owner );
session.persist( owner );
tx.commit();
assertThat( getNumberOfEntities( sessionFactory ) ).isEqualTo( 2 );
assertThat( getNumberOfAssociations( sessionFactory ) ).isEqualTo( expectedAssociationNumber() );
session.clear();
// read from inverse side
tx = session.beginTransaction();
soge = get( session, BankAccount.class, soge.getId() );
assertThat( soge.getOwners() ).hasSize( 1 );
assertThat( soge.getOwners() ).onProperty( "id" ).contains( owner.getId() );
tx.commit();
session.clear();
// read from non-inverse side and update data
tx = session.beginTransaction();
owner = get( session, AccountOwner.class, owner.getId() );
assertThat( owner.getBankAccounts() ).hasSize( 1 );
assertThat( owner.getBankAccounts() ).onProperty( "id" ).contains( soge.getId() );
BankAccount barclays = new BankAccount( "account_2" );
barclays.setAccountNumber( "ZZZ-009" );
barclays.getOwners().add( owner );
soge = owner.getBankAccounts().iterator().next();
soge.getOwners().remove( owner );
owner.getBankAccounts().add( barclays );
owner.getBankAccounts().remove( soge );
session.delete( soge );
tx.commit();
assertThat( getNumberOfEntities( sessionFactory ) ).isEqualTo( 2 );
assertThat( getNumberOfAssociations( sessionFactory ) ).isEqualTo( expectedAssociationNumber() );
session.clear();
// delete data
tx = session.beginTransaction();
owner = get( session, AccountOwner.class, owner.getId() );
assertThat( owner.getBankAccounts() ).hasSize( 1 );
assertThat( owner.getBankAccounts() ).onProperty( "id" ).contains( barclays.getId() );
barclays = owner.getBankAccounts().iterator().next();
barclays.getOwners().clear();
owner.getBankAccounts().clear();
session.delete( barclays );
session.delete( owner );
tx.commit();
assertThat( getNumberOfEntities( sessionFactory ) ).isEqualTo( 0 );
assertThat( getNumberOfAssociations( sessionFactory ) ).isEqualTo( 0 );
session.close();
checkCleanCache();
}
@Test
public void testManyToManyCompositeId() throws Exception {
Session session = openSession();
Transaction transaction = session.beginTransaction();
Car car = new Car();
car.setCarId( new Car.CarId( "Citroen", "AX" ) );
car.setHp( 20 );
session.persist( car );
Tire tire = new Tire();
tire.setTireId( new Tire.TireId( "Michelin", "B1" ) );
tire.setSize( 17d );
car.getTires().add( tire );
tire.getCars().add( car );
session.persist( tire );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
car = (Car) session.get( Car.class, car.getCarId() );
assertThat( car.getTires() ).hasSize( 1 );
assertThat( car.getTires().iterator().next().getCars() ).contains( car );
session.delete( car );
session.delete( car.getTires().iterator().next() );
transaction.commit();
session.close();
}
private int expectedAssociationNumber() {
if ( EnumSet.of( NEO4J_EMBEDDED, NEO4J_REMOTE ).contains( TestHelper.getCurrentDialectType() ) ) {
// Neo4j maps an association as one unique relationship either if it's a bidirectional or an unidirectional one.
return 1;
}
else {
return 2;
}
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
AccountOwner.class,
BankAccount.class,
Car.class,
Tire.class,
};
}
}