For experimental "transparent persistence" - Inserts added to PC

When inserting bean with transparent persistence the beans are registered with the persistence context. This is done to support the cases where the beans are inserted, a flush() occurs, the inserted bean is mutated and now dirty - we want that to be detected and get an update
This commit is contained in:
Robin Bygrave
2021-04-01 16:59:03 +13:00
parent ba397bbb0c
commit 0527f45f5a
9 changed files with 70 additions and 10 deletions
@@ -131,11 +131,6 @@ public class ScopedTransaction extends SpiTransactionProxy {
}
}
@Override
public void setTransparentPersistence(boolean transparentPersistence) {
current.getTransaction().setTransparentPersistence(transparentPersistence);
}
@Override
public void setRollbackOnly() {
current.setRollbackOnly();
@@ -147,6 +147,11 @@ public interface SpiTransaction extends Transaction {
*/
int depth();
/**
* Return true if transparent persistence is turned on.
*/
boolean isTransparentPersistence();
/**
* Return true if this transaction was created explicitly via
* <code>Ebean.beginTransaction()</code>.
@@ -43,6 +43,16 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
return transaction.getLabel();
}
@Override
public void setTransparentPersistence(boolean transparentPersistence) {
transaction.setTransparentPersistence(transparentPersistence);
}
@Override
public boolean isTransparentPersistence() {
return transaction.isTransparentPersistence();
}
@Override
public void commitAndContinue() {
transaction.commitAndContinue();
@@ -1038,6 +1038,10 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
if (!publish) {
beanDescriptor.setDraft(entityBean);
}
if (transaction.isTransparentPersistence() && idValue != null) {
// with getGeneratedKeys off we will not have a idValue
beanDescriptor.contextPut(transaction.getPersistenceContext(), idValue, entityBean);
}
}
public boolean isReference() {
@@ -100,6 +100,11 @@ class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCode
// do nothing
}
@Override
public boolean isTransparentPersistence() {
return false;
}
@Override
public void setLabel(String label) {
// do nothing
@@ -302,6 +302,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
this.batchMode = true;
}
@Override
public boolean isTransparentPersistence() {
return transparentPersistence;
}
@Override
public boolean isSkipCacheExplicit() {
return (skipCache != null && !skipCache);
@@ -30,6 +30,11 @@ class NoTransaction implements SpiTransaction {
// do nothing
}
@Override
public boolean isTransparentPersistence() {
return false;
}
@Override
public void setLabel(String label) {
// do nothing
@@ -60,11 +60,6 @@ class SavepointTransaction extends SpiTransactionProxy {
this.rollbackOnly = true;
}
@Override
public void setTransparentPersistence(boolean transparentPersistence) {
throw new IllegalStateException("This is not handled yet. Need to review this case.");
}
@Override
public void commit() {
if (rollbackOnly) {
@@ -17,6 +17,42 @@ import static org.assertj.core.api.Assertions.assertThat;
public class TestTransparentPersist extends BaseTestCase {
@Test
public void insertFlush_mutateFlush_expect_update() {
LoggedSql.start();
EBasicVer newBean;
try (Transaction transaction = DB.beginTransaction()) {
transaction.setTransparentPersistence(true); // EXPERIMENTAL feature
newBean = new EBasicVer("insertMe");
DB.save(newBean);
// flush - new bean needs to get registered into persistence context
transaction.flush();
// make it dirty, we expect it to execute an update on flush()
newBean.setName("make it dirty - auto save");
// flush again, auto persist dirty bean in persistence context
transaction.commit();
}
List<String> sql = LoggedSql.stop();
EBasicVer found = DB.find(EBasicVer.class, newBean.getId());
assertThat(found.getName()).isEqualTo("make it dirty - auto save");
assertThat(sql).hasSize(4);
assertThat(sql.get(0)).contains("insert into e_basicver");
assertThat(sql.get(1)).contains(" -- bind(");
assertThat(sql.get(2)).contains("update e_basicver set name=?, last_update=? where id=? and last_update=?");
assertThat(sql.get(3)).contains(" -- bind(");
DB.delete(found);
}
@Test
public void delete_expect_beanRemovedFromPersistenceContext() {