diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index 8d293e37b..c63fa0ddc 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -175,6 +175,14 @@ public class RedissonLiveObjectService implements RLiveObjectService { @Override public List persist(T... detachedObjects) { + return persist(RCascadeType.PERSIST, detachedObjects); + } + + public List merge(T... detachedObjects) { + return persist(RCascadeType.MERGE, detachedObjects); + } + + public List persist(RCascadeType type, T... detachedObjects) { CommandBatchService batchService = new CommandBatchService(commandExecutor); Map, Class> classCache = new HashMap<>(); @@ -191,19 +199,21 @@ public class RedissonLiveObjectService implements RLiveObjectService { name2id.put(liveMap.getName(), id); } - CommandBatchService checkExecutor = new CommandBatchService(batchService); - for (Entry entry : name2id.entrySet()) { - RMap map = new RedissonMap<>(checkExecutor, entry.getKey(), null, null, null); - map.containsKeyAsync("redisson_live_object"); - } + if (type == RCascadeType.PERSIST) { + CommandBatchService checkExecutor = new CommandBatchService(batchService); + for (Entry entry : name2id.entrySet()) { + RMap map = new RedissonMap<>(checkExecutor, entry.getKey(), null, null, null); + map.containsKeyAsync("redisson_live_object"); + } - BatchResult checkResponse = checkExecutor.execute(); - for (int i = 0; i < checkResponse.getResponses().size(); i++) { - Boolean value = (Boolean) checkResponse.getResponses().get(i); - if (value) { - List list = new ArrayList<>(name2id.values()); - Object id = list.get(i); - throw new IllegalArgumentException("Object with id=" + id + " already exists."); + BatchResult checkResponse = checkExecutor.execute(); + for (int i = 0; i < checkResponse.getResponses().size(); i++) { + Boolean value = (Boolean) checkResponse.getResponses().get(i); + if (value) { + List list = new ArrayList<>(name2id.values()); + Object id = list.get(i); + throw new IllegalArgumentException("Object with id=" + id + " already exists."); + } } } diff --git a/redisson/src/main/java/org/redisson/api/RLiveObjectService.java b/redisson/src/main/java/org/redisson/api/RLiveObjectService.java index ff0c50c17..f742ea13c 100644 --- a/redisson/src/main/java/org/redisson/api/RLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/api/RLiveObjectService.java @@ -144,6 +144,24 @@ public interface RLiveObjectService { */ T merge(T detachedObject); + /** + * Returns proxied object for the detached object. Transfers all the + * NON NULL field values to the redis server. It does not delete any + * existing data in redis in case of the field value is null. + * + * The class representing this object should have a field annotated with + * RId, and the object should hold a non null value in that field. + * + * If this object is not in redis then a new hash key will be created to + * store it. Otherwise overrides current object state in Redis with the given object state. + * + * @param Entity type + * @param detachedObjects - not proxied objects + * @return proxied object + * @throws IllegalArgumentException if the object is is a RLiveObject instance. + */ + List merge(T... detachedObjects); + /** * Returns proxied attached object for the detached object. Transfers all the * NON NULL field values to the redis server. Only when the it does diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index cac62b05e..bb84a5379 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -2289,6 +2289,36 @@ public class RedissonLiveObjectServiceTest extends BaseTest { } } + @Test + public void testBatchedMerge() { + Assertions.assertTimeout(Duration.ofSeconds(10), () -> { + RLiveObjectService s = redisson.getLiveObjectService(); + + List objects = new ArrayList<>(); + int objectsAmount = 100000; + for (int i = 0; i < objectsAmount; i++) { + TestREntity e = new TestREntity(); + e.setName("" + i); + e.setValue("value" + i); + objects.add(e); + } + List attachedObjects = s.merge(objects.toArray()); + assertThat(attachedObjects).hasSize(objectsAmount); + + objects.clear(); + for (int i = 0; i < objectsAmount; i++) { + TestREntity e = (TestREntity) attachedObjects.get(i); + e.setName("" + i); + e.setValue("value" + i*1000); + objects.add(e); + } + List attachedObjects2 = s.merge(objects.toArray()); + assertThat(attachedObjects2).hasSize(objectsAmount); + + assertThat(redisson.getKeys().count()).isEqualTo(objectsAmount); + }); + } + @Test public void testBatchedPersist() { Assertions.assertTimeout(Duration.ofSeconds(40), () -> {