Cascade LiveObjectService.merge whole object graph #649

pull/653/head
Nikita 8 years ago
parent 8500d4d002
commit a8cd9be1c8

@ -181,22 +181,17 @@ public class RedissonLiveObjectService implements RLiveObjectService {
@Override @Override
public <T> T merge(T detachedObject) { public <T> T merge(T detachedObject) {
T attachedObject = attach(detachedObject); Map<Object, Object> alreadyPersisted = new HashMap<Object, Object>();
getMap(attachedObject).fastPut("redisson_live_object", "1"); return persist(detachedObject, alreadyPersisted, false);
List<String> excludedFields = new ArrayList<String>();
String idFieldName = getRIdFieldName(detachedObject.getClass());
excludedFields.add(idFieldName);
copy(detachedObject, attachedObject, excludedFields);
return attachedObject;
} }
@Override @Override
public <T> T persist(T detachedObject) { public <T> T persist(T detachedObject) {
Map<Object, Object> alreadyPersisted = new HashMap<Object, Object>(); Map<Object, Object> alreadyPersisted = new HashMap<Object, Object>();
return persist(detachedObject, alreadyPersisted); return persist(detachedObject, alreadyPersisted, true);
} }
private <T> T persist(T detachedObject, Map<Object, Object> alreadyPersisted) { private <T> T persist(T detachedObject, Map<Object, Object> alreadyPersisted, boolean checkExistence) {
String idFieldName = getRIdFieldName(detachedObject.getClass()); String idFieldName = getRIdFieldName(detachedObject.getClass());
Object id = ClassUtils.getField(detachedObject, idFieldName); Object id = ClassUtils.getField(detachedObject, idFieldName);
if (id == null) { if (id == null) {
@ -214,78 +209,80 @@ public class RedissonLiveObjectService implements RLiveObjectService {
List<String> excludedFields = new ArrayList<String>(); List<String> excludedFields = new ArrayList<String>();
excludedFields.add(idFieldName); excludedFields.add(idFieldName);
if (liveMap.fastPut("redisson_live_object", "1")) { boolean fastResult = liveMap.fastPut("redisson_live_object", "1");
for (FieldDescription.InDefinedShape field : Introspectior.getFieldsDescription(detachedObject.getClass())) { if (checkExistence && !fastResult) {
Object object = ClassUtils.getField(detachedObject, field.getName()); 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) { if (rObject instanceof SortedSet) {
continue; ((RSortedSet)rObject).trySetComparator(((SortedSet)object).comparator());
} }
RObject rObject = objectBuilder.createObject(id, detachedObject.getClass(), object.getClass(), field.getName(), null); if (rObject instanceof Collection) {
if (rObject != null) { for (Object obj : (Collection<Object>)object) {
objectBuilder.store(rObject, field.getName(), liveMap); if (obj != null && obj.getClass().isAnnotationPresent(REntity.class)) {
Object persisted = alreadyPersisted.get(obj);
if (rObject instanceof SortedSet) { if (persisted == null) {
((RSortedSet)rObject).trySetComparator(((SortedSet)object).comparator()); persisted = persist(obj, alreadyPersisted, checkExistence);
}
if (rObject instanceof Collection) {
for (Object obj : (Collection<Object>)object) {
if (obj != null && obj.getClass().isAnnotationPresent(REntity.class)) {
Object persisted = alreadyPersisted.get(obj);
if (persisted == null) {
persisted = persist(obj, alreadyPersisted);
}
obj = persisted;
} }
((Collection)rObject).add(obj); obj = persisted;
} }
((Collection)rObject).add(obj);
} }
}
if (rObject instanceof Map) {
Map<Object, Object> rMap = (Map<Object, Object>) rObject; if (rObject instanceof Map) {
Map<?, ?> map = (Map<?, ?>)rObject; Map<Object, Object> rMap = (Map<Object, Object>) rObject;
for (Entry<?, ?> entry : map.entrySet()) { Map<?, ?> map = (Map<?, ?>)rObject;
Object key = entry.getKey(); for (Entry<?, ?> entry : map.entrySet()) {
Object value = entry.getValue(); Object key = entry.getKey();
Object value = entry.getValue();
if (key != null && key.getClass().isAnnotationPresent(REntity.class)) {
Object persisted = alreadyPersisted.get(key); if (key != null && key.getClass().isAnnotationPresent(REntity.class)) {
if (persisted == null) { Object persisted = alreadyPersisted.get(key);
persisted = persist(key, alreadyPersisted); if (persisted == null) {
} persisted = persist(key, alreadyPersisted, checkExistence);
key = persisted;
} }
key = persisted;
}
if (value != null && value.getClass().isAnnotationPresent(REntity.class)) { if (value != null && value.getClass().isAnnotationPresent(REntity.class)) {
Object persisted = alreadyPersisted.get(value); Object persisted = alreadyPersisted.get(value);
if (persisted == null) { if (persisted == null) {
persisted = persist(value, alreadyPersisted); persisted = persist(value, alreadyPersisted, checkExistence);
}
value = persisted;
} }
value = persisted;
rMap.put(key, value);
} }
rMap.put(key, value);
} }
excludedFields.add(field.getName());
} }
excludedFields.add(field.getName());
if (object.getClass().isAnnotationPresent(REntity.class)) { }
Object persisted = alreadyPersisted.get(object);
if (persisted == null) { if (object.getClass().isAnnotationPresent(REntity.class)) {
persisted = persist(object, alreadyPersisted); Object persisted = alreadyPersisted.get(object);
} if (persisted == null) {
persisted = persist(object, alreadyPersisted, checkExistence);
excludedFields.add(field.getName());
BeanUtil.pojo.setSimpleProperty(attachedObject, field.getName(), persisted);
} }
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 @Override

@ -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 @Test
public void testPersistList() { public void testPersistList() {
Customer customer = new Customer("12"); Customer customer = new Customer("12");

Loading…
Cancel
Save