diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index 932258203..f666f9ee5 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -181,22 +181,17 @@ public class RedissonLiveObjectService implements RLiveObjectService { @Override public T merge(T detachedObject) { - T attachedObject = attach(detachedObject); - getMap(attachedObject).fastPut("redisson_live_object", "1"); - List excludedFields = new ArrayList(); - String idFieldName = getRIdFieldName(detachedObject.getClass()); - excludedFields.add(idFieldName); - copy(detachedObject, attachedObject, excludedFields); - return attachedObject; + Map alreadyPersisted = new HashMap(); + return persist(detachedObject, alreadyPersisted, false); } - + @Override public T persist(T detachedObject) { Map alreadyPersisted = new HashMap(); - return persist(detachedObject, alreadyPersisted); + return persist(detachedObject, alreadyPersisted, true); } - private T persist(T detachedObject, Map alreadyPersisted) { + private T persist(T detachedObject, Map alreadyPersisted, boolean checkExistence) { String idFieldName = getRIdFieldName(detachedObject.getClass()); Object id = ClassUtils.getField(detachedObject, idFieldName); if (id == null) { @@ -214,78 +209,80 @@ public class RedissonLiveObjectService implements RLiveObjectService { List excludedFields = new ArrayList(); excludedFields.add(idFieldName); - if (liveMap.fastPut("redisson_live_object", "1")) { - for (FieldDescription.InDefinedShape field : Introspectior.getFieldsDescription(detachedObject.getClass())) { - Object object = ClassUtils.getField(detachedObject, field.getName()); + boolean fastResult = liveMap.fastPut("redisson_live_object", "1"); + if (checkExistence && !fastResult) { + throw new IllegalArgumentException("This REntity already exists."); + } + + for (FieldDescription.InDefinedShape field : Introspectior.getFieldsDescription(detachedObject.getClass())) { + Object object = ClassUtils.getField(detachedObject, field.getName()); + + if (object == null) { + continue; + } + + RObject rObject = objectBuilder.createObject(id, detachedObject.getClass(), object.getClass(), field.getName(), null); + if (rObject != null) { + objectBuilder.store(rObject, field.getName(), liveMap); - if (object == null) { - continue; + if (rObject instanceof SortedSet) { + ((RSortedSet)rObject).trySetComparator(((SortedSet)object).comparator()); } - RObject rObject = objectBuilder.createObject(id, detachedObject.getClass(), object.getClass(), field.getName(), null); - if (rObject != null) { - objectBuilder.store(rObject, field.getName(), liveMap); - - if (rObject instanceof SortedSet) { - ((RSortedSet)rObject).trySetComparator(((SortedSet)object).comparator()); - } - - if (rObject instanceof Collection) { - for (Object obj : (Collection)object) { - if (obj != null && obj.getClass().isAnnotationPresent(REntity.class)) { - Object persisted = alreadyPersisted.get(obj); - if (persisted == null) { - persisted = persist(obj, alreadyPersisted); - } - obj = persisted; + if (rObject instanceof Collection) { + for (Object obj : (Collection)object) { + if (obj != null && obj.getClass().isAnnotationPresent(REntity.class)) { + Object persisted = alreadyPersisted.get(obj); + if (persisted == null) { + persisted = persist(obj, alreadyPersisted, checkExistence); } - ((Collection)rObject).add(obj); + obj = persisted; } + ((Collection)rObject).add(obj); } - - if (rObject instanceof Map) { - Map rMap = (Map) rObject; - Map map = (Map)rObject; - for (Entry entry : map.entrySet()) { - Object key = entry.getKey(); - Object value = entry.getValue(); - - if (key != null && key.getClass().isAnnotationPresent(REntity.class)) { - Object persisted = alreadyPersisted.get(key); - if (persisted == null) { - persisted = persist(key, alreadyPersisted); - } - key = persisted; + } + + if (rObject instanceof Map) { + Map rMap = (Map) rObject; + Map map = (Map)rObject; + for (Entry entry : map.entrySet()) { + Object key = entry.getKey(); + Object value = entry.getValue(); + + if (key != null && key.getClass().isAnnotationPresent(REntity.class)) { + Object persisted = alreadyPersisted.get(key); + if (persisted == null) { + persisted = persist(key, alreadyPersisted, checkExistence); } + key = persisted; + } - if (value != null && value.getClass().isAnnotationPresent(REntity.class)) { - Object persisted = alreadyPersisted.get(value); - if (persisted == null) { - persisted = persist(value, alreadyPersisted); - } - value = persisted; + if (value != null && value.getClass().isAnnotationPresent(REntity.class)) { + Object persisted = alreadyPersisted.get(value); + if (persisted == null) { + persisted = persist(value, alreadyPersisted, checkExistence); } - - rMap.put(key, value); + value = persisted; } + + rMap.put(key, value); } - excludedFields.add(field.getName()); } - - if (object.getClass().isAnnotationPresent(REntity.class)) { - Object persisted = alreadyPersisted.get(object); - if (persisted == null) { - persisted = persist(object, alreadyPersisted); - } - - excludedFields.add(field.getName()); - BeanUtil.pojo.setSimpleProperty(attachedObject, field.getName(), persisted); + excludedFields.add(field.getName()); + } + + if (object.getClass().isAnnotationPresent(REntity.class)) { + Object persisted = alreadyPersisted.get(object); + if (persisted == null) { + persisted = persist(object, alreadyPersisted, checkExistence); } + + excludedFields.add(field.getName()); + BeanUtil.pojo.setSimpleProperty(attachedObject, field.getName(), persisted); } - copy(detachedObject, attachedObject, excludedFields); - return attachedObject; } - throw new IllegalArgumentException("This REntity already exists."); + copy(detachedObject, attachedObject, excludedFields); + return attachedObject; } @Override diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index aea26accd..2ea34d21b 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -551,6 +551,32 @@ public class RedissonLiveObjectServiceTest extends BaseTest { } } + @Test + public void testMergeList() { + Customer customer = new Customer("12"); + Order order = new Order(customer); + customer.getOrders().add(order); + Order order2 = new Order(customer); + customer.getOrders().add(order2); + + redisson.getLiveObjectService().merge(customer); + + Customer mergedCustomer = redisson.getLiveObjectService().get(Customer.class, "12"); + assertThat(mergedCustomer.getOrders().size()).isEqualTo(2); + for (Order orderElement : mergedCustomer.getOrders()) { + assertThat(orderElement.getId()).isNotNull(); + assertThat(orderElement.getCustomer().getId()).isEqualTo("12"); + } + + try { + redisson.getLiveObjectService().persist(customer); + fail("Should not be here"); + } catch (Exception e) { + assertEquals("This REntity already exists.", e.getMessage()); + } + } + + @Test public void testPersistList() { Customer customer = new Customer("12");