package org.tests.transaction;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.Transaction;
import org.tests.model.m2m.MnyB;
import org.tests.model.m2m.MnyC;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
public class TestBeanStateReset extends BaseTestCase {
private static final Logger logger = LoggerFactory.getLogger(TestBeanStateReset.class);
@Test
public void resetForInsert() {
// setup to fail foreign key constraint
MnyC c = new MnyC();
c.setId(Long.MAX_VALUE);
MnyB b = new MnyB();
b.getCs().add(c);
try {
// inserts of b succeeds but intersection insert fails FK check on c
b.save();
} catch (PersistenceException e) {
logger.info("expected error " + e.getMessage());
Ebean.getBeanState(b).resetForInsert();
b.getCs().clear();
LoggedSqlCollector.start();
b.setName("mod");
b.save();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql.get(0)).contains("insert into mny_b (id, name, version, when_created, when_modified, a_id) values (");
}
}
@Test
public void alternativeVia_persistCascadeOff_with_commitAndContinue() {
// setup to fail foreign key constraint when using cascade save
MnyC c = new MnyC();
c.setId(Long.MAX_VALUE);
MnyB b = new MnyB();
b.getCs().add(c);
Transaction transaction = Ebean.beginTransaction();
try {
// turn off cascade ...
transaction.setPersistCascade(false);
b.save();
// commit at this point
transaction.commitAndContinue();
try {
// turn on cascade ... such that the ManyToMany is persisted
transaction.setPersistCascade(true);
// save b again which this time cascades to the ManyToMany
// but this fails due to FK on ManyToMany
b.save();
// we actually don't get here due to the FK error
transaction.commit();
} catch (PersistenceException e) {
// so we failed the second save but that is ok'ish
// we handle this exception knowing b got inserted and committed
// and that the inserts into the intersection table failed
logger.info("The ManyToMany intersection error: " + e.getMessage());
}
} finally {
// performs a rollback as the commit at line:80 does not happen
transaction.end();
}
// assert our insert prior to the commitAndContinue succeeded
MnyB madeIt = Ebean.find(MnyB.class, b.getId());
assertNotNull(madeIt);
}
}