diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java index e0ab928c5..d831623c0 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java @@ -76,6 +76,11 @@ public final class PersistRequestBean extends PersistRequest implements BeanP */ private Integer beanHash; + /** + * Flag set if this is a stateless update. + */ + private boolean statelessUpdate; + private boolean notifyCache; private boolean deleteMissingChildren; @@ -134,6 +139,7 @@ public final class PersistRequestBean extends PersistRequest implements BeanP if (intercept.isNew()) { // 'stateless update' - set loaded properties as dirty intercept.setNewBeanForUpdate(); + statelessUpdate = true; } // Mark Mutable scalar properties (like Hstore) as dirty where necessary beanDescriptor.checkMutableProperties(intercept); @@ -501,8 +507,19 @@ public final class PersistRequestBean extends PersistRequest implements BeanP String m = Message.msg("persist.conc2", "" + rowCount); throw new OptimisticLockException(m, null, bean); } - if (type == Type.DELETE) { - postDelete(); + switch (type) { + case DELETE: postDelete(); break; + case UPDATE: postUpdate(); break; + default: // do nothing + } + } + + /** + * Clear the bean from the PersistenceContext (L1 cache) for stateless updates. + */ + private void postUpdate() { + if (statelessUpdate) { + transaction.getPersistenceContext().clear(beanDescriptor.getBeanType(), idValue); } } diff --git a/src/test/java/com/avaje/tests/persistencecontext/TestPersistenceContextQueryScope.java b/src/test/java/com/avaje/tests/persistencecontext/TestPersistenceContextQueryScope.java index e91d5439b..ee036322b 100644 --- a/src/test/java/com/avaje/tests/persistencecontext/TestPersistenceContextQueryScope.java +++ b/src/test/java/com/avaje/tests/persistencecontext/TestPersistenceContextQueryScope.java @@ -2,6 +2,7 @@ package com.avaje.tests.persistencecontext; import com.avaje.ebean.BaseTestCase; import com.avaje.ebean.Ebean; +import com.avaje.ebean.SqlUpdate; import com.avaje.tests.model.basic.EBasicVer; import org.junit.Test; @@ -25,13 +26,12 @@ public class TestPersistenceContextQueryScope extends BaseTestCase { try { EBasicVer bean1 = Ebean.find(EBasicVer.class, bean.getId()); - // do an update of the name - EBasicVer updateBean = new EBasicVer(); - updateBean.setId(bean.getId()); - updateBean.setName("second"); - - // perform an update to the DB - Ebean.update(updateBean); + // do an update of the name in the DB + SqlUpdate sqlUpdate = Ebean.createSqlUpdate("update e_basicver set name=? where id=?"); + sqlUpdate.setParameter(1, "second"); + sqlUpdate.setParameter(2, bean.getId()); + int rowCount = sqlUpdate.execute(); + assertEquals(1, rowCount); // fetch the bean again... but doesn't hit DB as it // is in the PersistenceContext which is transaction scoped diff --git a/src/test/java/com/avaje/tests/transaction/TestStatelessUpdateClearPC.java b/src/test/java/com/avaje/tests/transaction/TestStatelessUpdateClearPC.java new file mode 100644 index 000000000..c2bded3bc --- /dev/null +++ b/src/test/java/com/avaje/tests/transaction/TestStatelessUpdateClearPC.java @@ -0,0 +1,38 @@ +package com.avaje.tests.transaction; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.tests.model.basic.EBasic; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class TestStatelessUpdateClearPC extends BaseTestCase { + + @Test + public void test() { + + + Ebean.beginTransaction(); + + EBasic newUser = new EBasic(); + newUser.setName("any@email.com"); + Ebean.save(newUser); + + // load the bean into the persistence context + EBasic dummyLoadedUser = Ebean.find(EBasic.class, newUser.getId()); // This row is added + assertNotNull(dummyLoadedUser); + + // stateless update (should clear the bean from the persistence context) + EBasic updateUser = new EBasic(); + updateUser.setId(newUser.getId()); + updateUser.setName("anyNew@email.com"); + Ebean.update(updateUser); + + EBasic loadedUser = Ebean.find(EBasic.class, newUser.getId()); + assertEquals("anyNew@email.com", loadedUser.getName()); + + Ebean.rollbackTransaction(); + } +}