From f2957b35cd8920ecf36655b7acc958513cfbec24 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 3 Oct 2016 18:14:48 +0300 Subject: [PATCH] Cascade delete object graph for LiveObjectService #650 --- .../redisson/RedissonLiveObjectService.java | 52 ++++++++++++++++--- .../RedissonLiveObjectServiceTest.java | 26 ++++++++++ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index f666f9ee5..ec0958fdd 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -19,7 +19,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; @@ -71,13 +70,8 @@ import jodd.bean.BeanUtil; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.field.FieldList; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.method.ParameterDescription; -import net.bytebuddy.description.modifier.Visibility; -import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; -import net.bytebuddy.implementation.MethodCall; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.bind.annotation.FieldProxy; import net.bytebuddy.matcher.ElementMatchers; @@ -418,13 +412,57 @@ public class RedissonLiveObjectService implements RLiveObjectService { } } - @Override public void delete(T attachedObject) { + Set deleted = new HashSet(); + delete(attachedObject, deleted); + } + + public void delete(T attachedObject, Set deleted) { validateAttached(attachedObject); + + for (Entry obj : getMap(attachedObject).entrySet()) { + if (obj.getValue() instanceof RSortedSet) { + deleteCollection(deleted, (Iterable)obj.getValue()); + ((RObject)obj.getValue()).delete(); + } else if (obj.getValue() instanceof RDeque) { + deleteCollection(deleted, (Iterable)obj.getValue()); + ((RObject)obj.getValue()).delete(); + } else if (obj.getValue() instanceof RQueue) { + deleteCollection(deleted, (Iterable)obj.getValue()); + ((RObject)obj.getValue()).delete(); + } else if (obj.getValue() instanceof RSet) { + deleteCollection(deleted, (Iterable)obj.getValue()); + ((RObject)obj.getValue()).delete(); + } else if (obj.getValue() instanceof RList) { + deleteCollection(deleted, (Iterable)obj.getValue()); + ((RObject)obj.getValue()).delete(); + } + + if (isLiveObject(obj.getValue())) { + if (deleted.add(getMap(obj.getValue()).getName())) { + delete(obj.getValue(), deleted); + } + } else if (obj.getValue() instanceof RMap) { + RMap map = (RMap)obj.getValue(); + deleteCollection(deleted, map.keySet()); + deleteCollection(deleted, map.values()); + ((RObject)obj.getValue()).delete(); + } + } asLiveObject(attachedObject).delete(); } + private void deleteCollection(Set deleted, Iterable objs) { + for (Object object : objs) { + if (isLiveObject(object)) { + if (deleted.add(getMap(object).getName())) { + delete(object, deleted); + } + } + } + } + @Override public void delete(Class entityClass, K id) { asLiveObject(get(entityClass, id)).delete(); diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index 2ea34d21b..1731bf782 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -1272,6 +1272,32 @@ public class RedissonLiveObjectServiceTest extends BaseTest { Order order = new Order(customer); order = redisson.getLiveObjectService().persist(order); } + + @Test + public void testDeleteList() { + Customer customer = new Customer("12"); + Order order = new Order(customer); + customer.getOrders().add(order); + Order order2 = new Order(customer); + customer.getOrders().add(order2); + + order = redisson.getLiveObjectService().persist(order); + assertThat(redisson.getKeys().count()).isEqualTo(5); + + redisson.getLiveObjectService().delete(order.getCustomer()); + assertThat(redisson.getKeys().count()).isEqualTo(1); + } + + + @Test + public void testDelete() { + Customer customer = new Customer("12"); + Order order = new Order(customer); + order = redisson.getLiveObjectService().persist(order); + assertThat(redisson.getKeys().count()).isEqualTo(3); + redisson.getLiveObjectService().delete(order); + assertThat(redisson.getKeys().count()).isEqualTo(1); + } @Test public void testObjectShouldBeAttached() {