diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index 8636e6a62..c5e98fb80 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -33,6 +33,7 @@ import org.redisson.api.annotation.*; import org.redisson.api.condition.Condition; import org.redisson.client.codec.StringCodec; import org.redisson.client.protocol.RedisCommand; +import org.redisson.client.protocol.RedisCommands; import org.redisson.client.protocol.convertor.Convertor; import org.redisson.client.protocol.decoder.ListMultiDecoder2; import org.redisson.client.protocol.decoder.ListScanResult; @@ -65,7 +66,6 @@ public class RedissonLiveObjectService implements RLiveObjectService { private final ConcurrentMap, Class> classCache; private final CommandAsyncExecutor commandExecutor; private final LiveObjectSearch seachEngine; - private static final AtomicBoolean LISTENER_LATCH = new AtomicBoolean(); public RedissonLiveObjectService(ConcurrentMap, Class> classCache, CommandAsyncExecutor commandExecutor) { @@ -73,7 +73,7 @@ public class RedissonLiveObjectService implements RLiveObjectService { this.commandExecutor = commandExecutor; this.seachEngine = new LiveObjectSearch(commandExecutor); - if (LISTENER_LATCH.compareAndSet(false, true)) { + if (commandExecutor.getServiceManager().getLiveObjectLatch().compareAndSet(false, true)) { RPatternTopic topic = new RedissonPatternTopic(StringCodec.INSTANCE, commandExecutor, "__keyevent@*:expired"); topic.addListenerAsync(String.class, (pattern, channel, msg) -> { if (msg.contains("redisson_live_object:")) { @@ -617,6 +617,8 @@ public class RedissonLiveObjectService implements RLiveObjectService { String mapName = namingScheme.getName(entityClass, id); Object liveObjectId = namingScheme.resolveId(mapName); + deleteCollections(id, entityClass, ce); + RMap liveMap = new RedissonMap<>(namingScheme.getCodec(), commandExecutor, mapName, null, null, null); Map values = liveMap.getAll(fieldNames); @@ -642,6 +644,8 @@ public class RedissonLiveObjectService implements RLiveObjectService { CommandBatchService ce = new CommandBatchService(commandExecutor); FieldList fields = Introspectior.getFieldsWithAnnotation(entityClass, RIndex.class); + deleteCollections(id, entityClass, ce); + NamingScheme namingScheme = commandExecutor.getObjectBuilder().getNamingScheme(entityClass); String mapName = namingScheme.getName(entityClass, id); Object liveObjectId = namingScheme.resolveId(mapName); @@ -661,6 +665,21 @@ public class RedissonLiveObjectService implements RLiveObjectService { ce.execute(); } + private void deleteCollections(Object id, Class entityClass, CommandBatchService ce) { + for (InDefinedShape field : Introspectior.getAllFields(entityClass)) { + try { + Field f = ClassUtils.getDeclaredField(entityClass, field.getName()); + RObject rObject = commandExecutor.getObjectBuilder().createObject(id, entityClass, f.getType(), field.getName()); + if (rObject != null) { + RedissonObject ro = (RedissonObject) rObject; + ce.writeAsync(ro.getRawName(), RedisCommands.DEL, ro.getRawName()); + } + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + } + public RFuture delete(Object id, Class entityClass, NamingScheme namingScheme, CommandBatchService ce) { FieldList fields = Introspectior.getFieldsWithAnnotation(entityClass, RIndex.class); Set fieldNames = fields.stream().map(f -> f.getName()).collect(Collectors.toSet()); diff --git a/redisson/src/main/java/org/redisson/connection/ServiceManager.java b/redisson/src/main/java/org/redisson/connection/ServiceManager.java index 6eb7589e2..2010ac10c 100644 --- a/redisson/src/main/java/org/redisson/connection/ServiceManager.java +++ b/redisson/src/main/java/org/redisson/connection/ServiceManager.java @@ -58,6 +58,7 @@ import java.net.UnknownHostException; import java.security.MessageDigest; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; @@ -432,4 +433,9 @@ public class ServiceManager { return id; } + private final AtomicBoolean liveObjectLatch = new AtomicBoolean(); + + public AtomicBoolean getLiveObjectLatch() { + return liveObjectLatch; + } } diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index eaffadd99..e637ee19d 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -328,6 +328,8 @@ public class RedissonLiveObjectServiceTest extends BaseTest { @RIndex private int num2; + private List coll; + protected TestIndexed() { } @@ -339,7 +341,15 @@ public class RedissonLiveObjectServiceTest extends BaseTest { public String getId() { return id; } - + + public List getColl() { + return coll; + } + + public void setColl(List coll) { + this.coll = coll; + } + public Boolean getBool1() { return bool1; } @@ -1716,11 +1726,11 @@ public class RedissonLiveObjectServiceTest extends BaseTest { myObject = service.persist(myObject); myObject.setName1("123345"); myObject.setNum1(455); - assertThat(redisson.getKeys().count()).isEqualTo(5); + myObject.setColl(Arrays.asList(1L, 2L)); + assertThat(redisson.getKeys().count()).isEqualTo(6); assertTrue(service.asLiveObject(myObject).isExists()); service.asRMap(myObject).expire(Duration.ofSeconds(1)); Thread.sleep(2000); - assertFalse(service.asLiveObject(myObject).isExists()); assertThat(redisson.getKeys().count()).isZero(); redisson.shutdown();