From 5912e3a081776af53a84ce07e4b8a28aa417e4b9 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 30 Sep 2016 13:42:43 +0300 Subject: [PATCH] Not persisted REntity object allowed to store automatically #641 --- .../redisson/RedissonLiveObjectService.java | 18 ++--- .../redisson/liveobject/misc/ClassUtils.java | 25 +++++++ .../redisson/misc/RedissonObjectFactory.java | 4 + .../RedissonLiveObjectServiceTest.java | 74 +++++++++++++++++++ 4 files changed, 112 insertions(+), 9 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index b06fcceff..d4d78cd4c 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -43,12 +43,12 @@ import org.redisson.liveobject.core.LiveObjectInterceptor; import org.redisson.liveobject.core.RExpirableInterceptor; import org.redisson.liveobject.core.RMapInterceptor; import org.redisson.liveobject.core.RObjectInterceptor; +import org.redisson.liveobject.misc.ClassUtils; import org.redisson.liveobject.misc.Introspectior; import org.redisson.liveobject.provider.ResolverProvider; import org.redisson.liveobject.resolver.Resolver; import jodd.bean.BeanCopy; -import jodd.bean.BeanUtil; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.field.FieldList; @@ -84,7 +84,7 @@ public class RedissonLiveObjectService implements RLiveObjectService { // } public RMap getMap(Object proxied) { - return BeanUtil.declared.getProperty(proxied, "liveObjectLiveMap"); + return ClassUtils.getField(proxied, "liveObjectLiveMap"); } @Override @@ -144,7 +144,7 @@ public class RedissonLiveObjectService implements RLiveObjectService { Class entityClass = (Class) detachedObject.getClass(); try { String idFieldName = getRIdFieldName(detachedObject.getClass()); - Object id = BeanUtil.declared.getProperty(detachedObject, idFieldName); + Object id = ClassUtils.getField(detachedObject, idFieldName); Class proxyClass = getProxyClass(entityClass); return instantiateLiveObject(proxyClass, id); } catch (Exception ex) { @@ -163,14 +163,14 @@ public class RedissonLiveObjectService implements RLiveObjectService { @Override public T persist(T detachedObject) { String idFieldName = getRIdFieldName(detachedObject.getClass()); - Object id = BeanUtil.declared.getProperty(detachedObject, idFieldName); + Object id = ClassUtils.getField(detachedObject, idFieldName); if (id == null) { try { id = generateId(detachedObject.getClass()); } catch (NoSuchFieldException e) { throw new IllegalArgumentException(e); } - BeanUtil.declared.setProperty(detachedObject, idFieldName, id); + ClassUtils.setField(detachedObject, idFieldName, id); } T attachedObject = attach(detachedObject); @@ -199,11 +199,11 @@ public class RedissonLiveObjectService implements RLiveObjectService { list.set(i, detachedObject); } } - BeanUtil.declared.setProperty(detached, obj.getKey(), list); + ClassUtils.setField(detached, obj.getKey(), list); } if (isLiveObject(obj.getValue())) { Object detachedObject = detach(obj.getValue()); - BeanUtil.declared.setProperty(detached, obj.getKey(), detachedObject); + ClassUtils.setField(detached, obj.getKey(), detachedObject); } } @@ -293,8 +293,8 @@ public class RedissonLiveObjectService implements RLiveObjectService { private T instantiateDetachedObject(Class cls, K id) throws Exception { T instance = instantiate(cls, id); String fieldName = getRIdFieldName(cls); - if (BeanUtil.declared.getProperty(instance, fieldName) == null) { - BeanUtil.declared.setProperty(instance, fieldName, id); + if (ClassUtils.getField(instance, fieldName) == null) { + ClassUtils.setField(instance, fieldName, id); } return instance; } diff --git a/redisson/src/main/java/org/redisson/liveobject/misc/ClassUtils.java b/redisson/src/main/java/org/redisson/liveobject/misc/ClassUtils.java index f711f3acd..4a3c02969 100644 --- a/redisson/src/main/java/org/redisson/liveobject/misc/ClassUtils.java +++ b/redisson/src/main/java/org/redisson/liveobject/misc/ClassUtils.java @@ -45,6 +45,7 @@ package org.redisson.liveobject.misc; +import java.lang.reflect.Field; import java.lang.reflect.Method; /** @@ -53,6 +54,30 @@ import java.lang.reflect.Method; */ public class ClassUtils { + public static void setField(Object obj, String fieldName, Object value) { + try { + Field field = obj.getClass().getDeclaredField(fieldName); + if (!field.isAccessible()) { + field.setAccessible(true); + } + field.set(obj, value); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + public static T getField(Object obj, String fieldName) { + try { + Field field = obj.getClass().getDeclaredField(fieldName); + if (!field.isAccessible()) { + field.setAccessible(true); + } + return (T) field.get(obj); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + /** * Searches through all methods looking for one with the specified name that * will take the specified paramaters even if the parameter types are more diff --git a/redisson/src/main/java/org/redisson/misc/RedissonObjectFactory.java b/redisson/src/main/java/org/redisson/misc/RedissonObjectFactory.java index 1ae3b378a..644e69d7f 100644 --- a/redisson/src/main/java/org/redisson/misc/RedissonObjectFactory.java +++ b/redisson/src/main/java/org/redisson/misc/RedissonObjectFactory.java @@ -154,6 +154,10 @@ public class RedissonObjectFactory { } public static RedissonReference toReference(RedissonClient redisson, Object object) { + if (object != null && object.getClass().isAnnotationPresent(REntity.class)) { + throw new IllegalArgumentException("REntity should be attached to Redisson before save"); + } + if (object instanceof RObject && !(object instanceof RLiveObject)) { RObject rObject = ((RObject) object); redisson.getCodecProvider().registerCodec((Class) rObject.getCodec().getClass(), (Class) rObject.getClass(), rObject.getName(), rObject.getCodec()); diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index 6ef1b31ab..f2d410314 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -1134,4 +1134,78 @@ public class RedissonLiveObjectServiceTest extends BaseTest { } } + @REntity + public static class Customer { + + @RId + private String id; + + private List orders = new ArrayList<>(); + + public Customer() { + } + + public Customer(String id) { + super(); + this.id = id; + } + + public void addOrder(Order order) { + getOrders().add(order); + } + + public void setOrders(List orders) { + this.orders = orders; + } + + public List getOrders() { + return orders; + } + + public String getId() { + return id; + } + + } + + @REntity + public static class Order { + + @RId(generator = DistributedAtomicLongIdGenerator.class) + private Long id; + + public Long getId() { + return id; + } + + } + + @Test(expected = IllegalArgumentException.class) + public void testObjectShouldNotBeAttached() { + Customer customer = new Customer("12"); + customer = redisson.getLiveObjectService().persist(customer); + Order order = new Order(); + customer.getOrders().add(order); + } + + @Test + public void testObjectShouldBeAttached() { + Customer customer = new Customer("12"); + customer = redisson.getLiveObjectService().persist(customer); + Order order = new Order(); + order = redisson.getLiveObjectService().persist(order); + customer.getOrders().add(order); + + customer = redisson.getLiveObjectService().detach(customer); + assertThat(customer.getClass()).isSameAs(Customer.class); + assertThat(customer.getId()).isNotNull(); + List orders = customer.getOrders(); + assertThat(orders.get(0)).isNotNull(); + + customer = redisson.getLiveObjectService().get(Customer.class, customer.getId()); + assertThat(customer.getId()).isNotNull(); + assertThat(customer.getOrders().get(0)).isNotNull(); + } + + }