Fixed - add batched merge() method to RLiveObjectService interface #3773

pull/3782/head
Nikita Koksharov 4 years ago
parent c1b19a57cb
commit 34c3d47bf5

@ -175,6 +175,14 @@ public class RedissonLiveObjectService implements RLiveObjectService {
@Override @Override
public <T> List<T> persist(T... detachedObjects) { public <T> List<T> persist(T... detachedObjects) {
return persist(RCascadeType.PERSIST, detachedObjects);
}
public <T> List<T> merge(T... detachedObjects) {
return persist(RCascadeType.MERGE, detachedObjects);
}
public <T> List<T> persist(RCascadeType type, T... detachedObjects) {
CommandBatchService batchService = new CommandBatchService(commandExecutor); CommandBatchService batchService = new CommandBatchService(commandExecutor);
Map<Class<?>, Class<?>> classCache = new HashMap<>(); Map<Class<?>, Class<?>> classCache = new HashMap<>();
@ -191,19 +199,21 @@ public class RedissonLiveObjectService implements RLiveObjectService {
name2id.put(liveMap.getName(), id); name2id.put(liveMap.getName(), id);
} }
CommandBatchService checkExecutor = new CommandBatchService(batchService); if (type == RCascadeType.PERSIST) {
for (Entry<String, Object> entry : name2id.entrySet()) { CommandBatchService checkExecutor = new CommandBatchService(batchService);
RMap<String, Object> map = new RedissonMap<>(checkExecutor, entry.getKey(), null, null, null); for (Entry<String, Object> entry : name2id.entrySet()) {
map.containsKeyAsync("redisson_live_object"); RMap<String, Object> map = new RedissonMap<>(checkExecutor, entry.getKey(), null, null, null);
} map.containsKeyAsync("redisson_live_object");
}
BatchResult<?> checkResponse = checkExecutor.execute(); BatchResult<?> checkResponse = checkExecutor.execute();
for (int i = 0; i < checkResponse.getResponses().size(); i++) { for (int i = 0; i < checkResponse.getResponses().size(); i++) {
Boolean value = (Boolean) checkResponse.getResponses().get(i); Boolean value = (Boolean) checkResponse.getResponses().get(i);
if (value) { if (value) {
List<Object> list = new ArrayList<>(name2id.values()); List<Object> list = new ArrayList<>(name2id.values());
Object id = list.get(i); Object id = list.get(i);
throw new IllegalArgumentException("Object with id=" + id + " already exists."); throw new IllegalArgumentException("Object with id=" + id + " already exists.");
}
} }
} }

@ -144,6 +144,24 @@ public interface RLiveObjectService {
*/ */
<T> T merge(T detachedObject); <T> T merge(T detachedObject);
/**
* Returns proxied object for the detached object. Transfers all the
* <b>NON NULL</b> 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 <T> Entity type
* @param detachedObjects - not proxied objects
* @return proxied object
* @throws IllegalArgumentException if the object is is a RLiveObject instance.
*/
<T> List<T> merge(T... detachedObjects);
/** /**
* Returns proxied attached object for the detached object. Transfers all the * Returns proxied attached object for the detached object. Transfers all the
* <b>NON NULL</b> field values to the redis server. Only when the it does * <b>NON NULL</b> field values to the redis server. Only when the it does

@ -2289,6 +2289,36 @@ public class RedissonLiveObjectServiceTest extends BaseTest {
} }
} }
@Test
public void testBatchedMerge() {
Assertions.assertTimeout(Duration.ofSeconds(10), () -> {
RLiveObjectService s = redisson.getLiveObjectService();
List<TestREntity> 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<Object> 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<Object> attachedObjects2 = s.merge(objects.toArray());
assertThat(attachedObjects2).hasSize(objectsAmount);
assertThat(redisson.getKeys().count()).isEqualTo(objectsAmount);
});
}
@Test @Test
public void testBatchedPersist() { public void testBatchedPersist() {
Assertions.assertTimeout(Duration.ofSeconds(40), () -> { Assertions.assertTimeout(Duration.ofSeconds(40), () -> {

Loading…
Cancel
Save