diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java index 6e95a114e..f5a1db07b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/ScopedTransaction.java @@ -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(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java index 74faeccb0..8c520f79e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java @@ -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 * Ebean.beginTransaction(). diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java index fe5351ddc..1652b56f6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java @@ -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(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java index c4d02cbf6..3f7d6e79a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java @@ -1038,6 +1038,10 @@ public final class PersistRequestBean 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() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java index 04d7a83a5..a94260fb6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java @@ -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 diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java index 2585c2b23..bb672cd33 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java @@ -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); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java index 5d593302f..92f0e1ca9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java @@ -30,6 +30,11 @@ class NoTransaction implements SpiTransaction { // do nothing } + @Override + public boolean isTransparentPersistence() { + return false; + } + @Override public void setLabel(String label) { // do nothing diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java index 7b596afec..b50122f5c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java @@ -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) { diff --git a/ebean-core/src/test/java/org/tests/transparentpersist/TestTransparentPersist.java b/ebean-core/src/test/java/org/tests/transparentpersist/TestTransparentPersist.java index be5d8329b..a59ddda60 100644 --- a/ebean-core/src/test/java/org/tests/transparentpersist/TestTransparentPersist.java +++ b/ebean-core/src/test/java/org/tests/transparentpersist/TestTransparentPersist.java @@ -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 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() {