diff --git a/src/main/java/io/ebean/event/BeanDeleteIdRequest.java b/src/main/java/io/ebean/event/BeanDeleteIdRequest.java new file mode 100644 index 000000000..795886830 --- /dev/null +++ b/src/main/java/io/ebean/event/BeanDeleteIdRequest.java @@ -0,0 +1,26 @@ +package io.ebean.event; + +import io.ebean.EbeanServer; +import io.ebean.Transaction; + +/** + * A request to delete a bean by Id value. + */ +public interface BeanDeleteIdRequest { + + /** + * Return the server processing the request. + */ + EbeanServer getEbeanServer(); + + /** + * Return the Transaction associated with this request. + */ + Transaction getTransaction(); + + /** + * Returns the Id value of the bean being deleted. + */ + Object getId(); + +} diff --git a/src/main/java/io/ebean/event/BeanPersistAdapter.java b/src/main/java/io/ebean/event/BeanPersistAdapter.java index 6e38ce2aa..4b6cf2cc6 100644 --- a/src/main/java/io/ebean/event/BeanPersistAdapter.java +++ b/src/main/java/io/ebean/event/BeanPersistAdapter.java @@ -87,4 +87,11 @@ public abstract class BeanPersistAdapter implements BeanPersistController { public void postSoftDelete(BeanPersistRequest request) { } + /** + * Does nothing by default. + */ + @Override + public void preDelete(BeanDeleteIdRequest request) { + + } } diff --git a/src/main/java/io/ebean/event/BeanPersistController.java b/src/main/java/io/ebean/event/BeanPersistController.java index 6c55cf310..15160cb28 100644 --- a/src/main/java/io/ebean/event/BeanPersistController.java +++ b/src/main/java/io/ebean/event/BeanPersistController.java @@ -92,6 +92,11 @@ public interface BeanPersistController { */ boolean preSoftDelete(BeanPersistRequest request); + /** + * Prior to a delete by id perform some action. + */ + void preDelete(BeanDeleteIdRequest request); + /** * Called after the insert was performed. */ diff --git a/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java b/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java index ff6bfe6c1..639a856ad 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java +++ b/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.deploy; +import io.ebean.event.BeanDeleteIdRequest; import io.ebean.event.BeanPersistController; import io.ebean.event.BeanPersistRequest; @@ -147,6 +148,13 @@ public class ChainedBeanPersistController implements BeanPersistController { return true; } + @Override + public void preDelete(BeanDeleteIdRequest request) { + for (BeanPersistController aChain : chain) { + aChain.preDelete(request); + } + } + @Override public boolean preInsert(BeanPersistRequest request) { for (BeanPersistController aChain : chain) { diff --git a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index 8459d8e2d..cbf9aba38 100644 --- a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -9,6 +9,7 @@ import io.ebean.bean.BeanCollection; import io.ebean.bean.BeanCollection.ModifyListenMode; import io.ebean.bean.EntityBean; import io.ebean.bean.PersistenceContext; +import io.ebean.event.BeanPersistController; import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.api.SpiTransaction; import io.ebeaninternal.api.SpiUpdate; @@ -718,6 +719,7 @@ public final class DefaultPersister implements Persister { } // use Id's to update L2 cache rather than Bulk table event + notifyDeleteById(descriptor, id, idList, transaction); deleteById.setAutoTableMod(false); if (idList != null) { t.getEvent().addDeleteByIdList(descriptor, idList); @@ -738,6 +740,22 @@ public final class DefaultPersister implements Persister { return rows; } + private void notifyDeleteById(BeanDescriptor descriptor, Object id, List idList, Transaction transaction) { + + BeanPersistController controller = descriptor.getPersistController(); + if (controller != null) { + DeleteIdRequest request = new DeleteIdRequest(server, transaction, id); + if (idList == null) { + controller.preDelete(request); + } else { + for (Object idValue : idList) { + request.setId(idValue); + controller.preDelete(request); + } + } + } + } + /** * We need to create and execute a query to get the foreign key values as * the delete cascades to them (foreign keys). diff --git a/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java b/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java new file mode 100644 index 000000000..0cad9918a --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java @@ -0,0 +1,37 @@ +package io.ebeaninternal.server.persist; + +import io.ebean.EbeanServer; +import io.ebean.Transaction; +import io.ebean.event.BeanDeleteIdRequest; +import io.ebeaninternal.api.SpiEbeanServer; + +class DeleteIdRequest implements BeanDeleteIdRequest { + + private final EbeanServer server; + private final Transaction transaction; + private Object id; + + DeleteIdRequest(SpiEbeanServer server, Transaction transaction, Object id) { + this.server = server; + this.transaction = transaction; + } + + void setId(Object id) { + this.id = id; + } + + @Override + public EbeanServer getEbeanServer() { + return server; + } + + @Override + public Transaction getTransaction() { + return transaction; + } + + @Override + public Object getId() { + return id; + } +} diff --git a/src/test/java/io/ebean/event/BeanPersistControllerTest.java b/src/test/java/io/ebean/event/BeanPersistControllerTest.java index 03f7a1170..58d351a1c 100644 --- a/src/test/java/io/ebean/event/BeanPersistControllerTest.java +++ b/src/test/java/io/ebean/event/BeanPersistControllerTest.java @@ -4,19 +4,20 @@ package io.ebean.event; import io.ebean.EbeanServer; import io.ebean.EbeanServerFactory; import io.ebean.config.ServerConfig; -import org.tests.model.basic.EBasicVer; import org.junit.Test; +import org.tests.model.basic.EBasicVer; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; public class BeanPersistControllerTest { - PersistAdapter continuePersistingAdapter = new PersistAdapter(true); + private PersistAdapter continuePersistingAdapter = new PersistAdapter(true); - PersistAdapter stopPersistingAdapter = new PersistAdapter(false); + private PersistAdapter stopPersistingAdapter = new PersistAdapter(false); @Test public void testInsertUpdateDelete_given_continuePersistingAdapter() { @@ -64,7 +65,17 @@ public class BeanPersistControllerTest { ebeanServer.delete(bean); assertThat(stopPersistingAdapter.methodsCalled).hasSize(1); assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDelete"); + stopPersistingAdapter.methodsCalled.clear(); + ebeanServer.delete(EBasicVer.class, 22); + assertThat(stopPersistingAdapter.methodsCalled).hasSize(1); + assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById"); + stopPersistingAdapter.methodsCalled.clear(); + + ebeanServer.deleteAll(EBasicVer.class, Arrays.asList(22,23,24)); + assertThat(stopPersistingAdapter.methodsCalled).hasSize(3); + assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById", "preDeleteById", "preDeleteById"); + stopPersistingAdapter.methodsCalled.clear(); } private EbeanServer getEbeanServer(PersistAdapter persistAdapter) { @@ -136,6 +147,11 @@ public class BeanPersistControllerTest { public void postUpdate(BeanPersistRequest request) { methodsCalled.add("postUpdate"); } + + @Override + public void preDelete(BeanDeleteIdRequest request) { + methodsCalled.add("preDeleteById"); + } } }