/*
* 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.dialectinvocations;
import static org.fest.assertions.Assertions.assertThat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.ogm.backendtck.associations.onetoone.Husband;
import org.hibernate.ogm.backendtck.associations.onetoone.Wife;
import org.hibernate.ogm.dialect.batch.spi.BatchableGridDialect;
import org.hibernate.ogm.dialect.batch.spi.GroupingByEntityDialect;
import org.hibernate.ogm.dialect.impl.GridDialects;
import org.hibernate.ogm.dialect.spi.GridDialect;
import org.hibernate.ogm.utils.GridDialectType;
import org.hibernate.ogm.utils.SkipByGridDialect;
import org.hibernate.ogm.utils.TestForIssue;
import org.junit.Test;
/**
* @author Emmanuel Bernard emmanuel@hibernate.org
* @author Guillaume Smet
*/
@SkipByGridDialect(value = { GridDialectType.NEO4J_REMOTE, GridDialectType.NEO4J_EMBEDDED, GridDialectType.INFINISPAN_REMOTE },
comment = "For Cassandra and Neo4j, the getAssociation always return an association, thus we don't have the createAssociation call. " +
"Redis Hash is just weird. Infinispan Remote needs to be investigated.")
@TestForIssue(jiraKey = "OGM-1152")
public class GridDialectOperationInvocationsForOneToOneTest extends AbstractGridDialectOperationInvocationsTest {
@Test
public void testBidirectionalOneToOne() throws Exception {
GridDialect gridDialect = getGridDialect();
final Session session = openSession();
Transaction transaction = session.beginTransaction();
Husband husband = new Husband( "alex" );
husband.setName( "Alex" );
Wife wife = new Wife( "bea" );
wife.setName( "Bea" );
husband.setWife( wife );
wife.setHusband( husband );
session.persist( husband );
session.persist( wife );
transaction.commit();
session.clear();
if ( GridDialects.hasFacet( gridDialect, GroupingByEntityDialect.class ) ) {
if ( isDuplicateInsertPreventionStrategyNative( gridDialect ) ) {
assertThat( getOperations() ).containsExactly(
"getTuple", // when adding Husband, ORM looks at Wife and checks if it is transient
// since it is transient and id is manually set, this leads to a lookup
"createTuple", // creating Husband tuple
"createTuple", // creating Wife tuple
"getAssociation", // read the association info from Wife to Husband
// before that, executes the batch containing the 2 insertOrUpdateTuple operations
"createAssociation", // could not find the association so create one
"executeBatch[group[insertOrUpdateTuple,insertOrUpdateTuple],group[insertOrUpdateTuple,insertOrUpdateAssociation]]"
// inserting Husband without FK
// update Husband with wife FK
// inserting Wife without association
// actually update the (inverse) association with a wife -> husband entry
);
}
else {
assertThat( getOperations() ).containsExactly(
"getTuple", // when adding Husband, ORM looks at Wife and checks if it is transient
// since it is transient and id is manually set, this leads to a lookup
"getTuple", // when inserting Husband, we do a lookup to check whether it is already present
// DuplicateInsertPreventionStrategy.LOOKUP
"createTuple", // creating Husband tuple
"getTuple", // when inserting Wife, we do a lookup to check whether it is already present
// DuplicateInsertPreventionStrategy.LOOKUP
"createTuple", // creating Wife tuple
"getAssociation", // read the association info from Wife to Husband
"createAssociation", // could not find the association so create one
"executeBatch[group[insertOrUpdateTuple,insertOrUpdateTuple],group[insertOrUpdateTuple,insertOrUpdateAssociation]]"
// inserting Husband without FK
// update Husband with wife FK
// inserting Wife without association
// actually update the (inverse) association with a wife -> husband entry
);
}
}
else if ( GridDialects.hasFacet( gridDialect, BatchableGridDialect.class ) ) {
assertThat( getOperations() ).containsExactly(
"getTuple", // when adding Husband, ORM looks at Wife and checks if it is transient
// since it is transient and id is manually set, this leads to a lookup
"createTuple", // creating Husband tuple
"createTuple", // creating Wife tuple
"getAssociation", // read the association info from Wife to Husband
// before that, executes the batch containing the 2 insertOrUpdateTuple operations
"createAssociation", // could not find the association so create one
"executeBatch[group[insertOrUpdateAssociation]]" // execute the batch of insert/update operations
);
}
else if ( isDuplicateInsertPreventionStrategyNative( gridDialect ) ) {
assertThat( getOperations() ).containsExactly(
"getTuple", // when adding Husband, ORM looks at Wife and checks if it is transient
// since it is transient and id is manually set, this leads to a lookup
"createTuple", // creating Husband tuple
"insertOrUpdateTuple", // inserting Husband without fk
"createTuple", // creating Wife tuple
"insertOrUpdateTuple", // inserting Wife without association
"insertOrUpdateTuple", // update Husband with wife FK
"getAssociation", // read the association info from Wife to Husband
"createAssociation", // could not find the association so create one
"insertOrUpdateAssociation" // actually update the (inverse) association with a wife -> husband
// entry
);
}
else {
assertThat( getOperations() ).containsExactly(
"getTuple", // when adding Husband, ORM looks at Wife and checks if it is transient
// since it is transient and id is manually set, this leads to a lookup
"getTuple", // when inserting Husband, we do a lookup to check whether it is already present
// DuplicateInsertPreventionStrategy.LOOKUP
"createTuple", // creating Husband tuple
"insertOrUpdateTuple", // inserting Husband without fk
"getTuple", // when inserting Wife, we do a lookup to check whether it is already present
// DuplicateInsertPreventionStrategy.LOOKUP
"createTuple", // creating Wife tuple
"insertOrUpdateTuple", // inserting Wife without association
"insertOrUpdateTuple", // update Husband with wife FK
"getAssociation", // read the association info from Wife to Husband
"createAssociation", // could not find the association so create one
"insertOrUpdateAssociation" // actually update the (inverse) association with a wife -> husband
// entry
);
}
transaction = session.beginTransaction();
husband = (Husband) session.get( Husband.class, husband.getId() );
session.clear();
session.delete( husband );
session.delete( husband.getWife() );
transaction.commit();
session.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Husband.class, Wife.class };
}
}