From 4f2f9a2e99e641e8ad0ba878f058dd1f17bd3ca4 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Thu, 27 Jun 2013 23:23:20 +1200 Subject: [PATCH] Fix for Issue 32 Deleted bean not removed from PersistenceContext --- .../server/core/PersistRequestBean.java | 45 +++++++++------ .../server/persist/dml/DeleteHandler.java | 3 + .../TestDeleteFromPersistenceContext.java | 55 +++++++++++++++++++ 3 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 src/test/java/com/avaje/tests/transaction/TestDeleteFromPersistenceContext.java 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 50101b5c6..e23e922f8 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java @@ -176,23 +176,26 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist return beanPersistListener != null; } - public void notifyCache() { - if (notifyCache) { - switch (type) { - case INSERT: - beanDescriptor.cacheInsert(idValue, this); - break; - case UPDATE: - beanDescriptor.cacheUpdate(idValue, this); - break; - case DELETE: - beanDescriptor.cacheDelete(idValue, this); - break; - default: - throw new IllegalStateException("Invalid type "+type); - } - } - } + /** + * Notify/Update the local L2 cache after the transaction has successfully committed. + */ + public void notifyCache() { + if (notifyCache) { + switch (type) { + case INSERT: + beanDescriptor.cacheInsert(idValue, this); + break; + case UPDATE: + beanDescriptor.cacheUpdate(idValue, this); + break; + case DELETE: + // Bean deleted from cache early via postDelete() + break; + default: + throw new IllegalStateException("Invalid type " + type); + } + } + } public void addToPersistMap(BeanPersistIdMap beanPersistMap) { @@ -510,6 +513,14 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist } } + public void postDelete() { + + // Delete the bean from the PersistenceContent + transaction.getPersistenceContext().clear(beanDescriptor.getBeanType(), idValue); + // Delete from cache early even if transaction fails + beanDescriptor.cacheDelete(idValue, this); + } + /** * Post processing. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/persist/dml/DeleteHandler.java b/src/main/java/com/avaje/ebeaninternal/server/persist/dml/DeleteHandler.java index 69b3f5701..0784eee15 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/persist/dml/DeleteHandler.java +++ b/src/main/java/com/avaje/ebeaninternal/server/persist/dml/DeleteHandler.java @@ -52,6 +52,9 @@ public class DeleteHandler extends DmlHandler { public void execute() throws SQLException, OptimisticLockException { int rowCount = dataBind.executeUpdate(); checkRowCount(rowCount); + + // Deletes the bean from the PersistenceContext + persistRequest.postDelete(); } @Override diff --git a/src/test/java/com/avaje/tests/transaction/TestDeleteFromPersistenceContext.java b/src/test/java/com/avaje/tests/transaction/TestDeleteFromPersistenceContext.java new file mode 100644 index 000000000..9ac5aee33 --- /dev/null +++ b/src/test/java/com/avaje/tests/transaction/TestDeleteFromPersistenceContext.java @@ -0,0 +1,55 @@ +package com.avaje.tests.transaction; + +import junit.framework.Assert; + +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.ebeaninternal.api.SpiTransaction; +import com.avaje.tests.model.basic.EBasicVer; +import com.avaje.tests.model.basic.ResetBasicData; + +public class TestDeleteFromPersistenceContext extends BaseTestCase { + + @Test + public void testDeleteBean() { + + ResetBasicData.reset(); + + EBasicVer bean = new EBasicVer(); + bean.setName("Please Delete Me"); + + Ebean.save(bean); + + SpiTransaction transaction = (SpiTransaction)Ebean.beginTransaction(); + try { + + EBasicVer bean2 = Ebean.find(EBasicVer.class, bean.getId()); + Assert.assertNotSame(bean, bean2); + + EBasicVer bean3 = Ebean.find(EBasicVer.class, bean.getId()); + // same instance from PersistenceContext + Assert.assertSame(bean2, bean3); + + Object bean4 = transaction.getPersistenceContext().get(EBasicVer.class, bean.getId()); + Assert.assertSame(bean2, bean4); + + Ebean.delete(bean2); + + Object bean5 = transaction.getPersistenceContext().get(EBasicVer.class, bean.getId()); + Assert.assertNull("Bean is deleted from PersistenceContext",bean5); + + EBasicVer bean6 = Ebean.find(EBasicVer.class).where().eq("id", bean.getId()).findUnique(); + Assert.assertNull("Bean where id eq is not found "+bean6, bean6); + + EBasicVer bean7 = Ebean.find(EBasicVer.class, bean.getId()); + Assert.assertNull("Bean is not expected to be found? "+bean7, bean7); + + } finally { + Ebean.endTransaction(); + } + + } + +}