How to convert a Hibernate proxy to a real entity object

后端 未结 10 849
离开以前
离开以前 2020-11-22 16:49

During a Hibernate Session, I am loading some objects and some of them are loaded as proxies due to lazy loading. It\'s all OK and I don\'t want to turn lazy lo

10条回答
  •  生来不讨喜
    2020-11-22 17:40

    I've written following code which cleans object from proxies (if they are not already initialized)

    public class PersistenceUtils {
    
        private static void cleanFromProxies(Object value, List handledObjects) {
            if ((value != null) && (!isProxy(value)) && !containsTotallyEqual(handledObjects, value)) {
                handledObjects.add(value);
                if (value instanceof Iterable) {
                    for (Object item : (Iterable) value) {
                        cleanFromProxies(item, handledObjects);
                    }
                } else if (value.getClass().isArray()) {
                    for (Object item : (Object[]) value) {
                        cleanFromProxies(item, handledObjects);
                    }
                }
                BeanInfo beanInfo = null;
                try {
                    beanInfo = Introspector.getBeanInfo(value.getClass());
                } catch (IntrospectionException e) {
                    // LOGGER.warn(e.getMessage(), e);
                }
                if (beanInfo != null) {
                    for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
                        try {
                            if ((property.getWriteMethod() != null) && (property.getReadMethod() != null)) {
                                Object fieldValue = property.getReadMethod().invoke(value);
                                if (isProxy(fieldValue)) {
                                    fieldValue = unproxyObject(fieldValue);
                                    property.getWriteMethod().invoke(value, fieldValue);
                                }
                                cleanFromProxies(fieldValue, handledObjects);
                            }
                        } catch (Exception e) {
                            // LOGGER.warn(e.getMessage(), e);
                        }
                    }
                }
            }
        }
    
        public static  T cleanFromProxies(T value) {
            T result = unproxyObject(value);
            cleanFromProxies(result, new ArrayList());
            return result;
        }
    
        private static boolean containsTotallyEqual(Collection collection, Object value) {
            if (CollectionUtils.isEmpty(collection)) {
                return false;
            }
            for (Object object : collection) {
                if (object == value) {
                    return true;
                }
            }
            return false;
        }
    
        public static boolean isProxy(Object value) {
            if (value == null) {
                return false;
            }
            if ((value instanceof HibernateProxy) || (value instanceof PersistentCollection)) {
                return true;
            }
            return false;
        }
    
        private static Object unproxyHibernateProxy(HibernateProxy hibernateProxy) {
            Object result = hibernateProxy.writeReplace();
            if (!(result instanceof SerializableProxy)) {
                return result;
            }
            return null;
        }
    
        @SuppressWarnings("unchecked")
        private static  T unproxyObject(T object) {
            if (isProxy(object)) {
                if (object instanceof PersistentCollection) {
                    PersistentCollection persistentCollection = (PersistentCollection) object;
                    return (T) unproxyPersistentCollection(persistentCollection);
                } else if (object instanceof HibernateProxy) {
                    HibernateProxy hibernateProxy = (HibernateProxy) object;
                    return (T) unproxyHibernateProxy(hibernateProxy);
                } else {
                    return null;
                }
            }
            return object;
        }
    
        private static Object unproxyPersistentCollection(PersistentCollection persistentCollection) {
            if (persistentCollection instanceof PersistentSet) {
                return unproxyPersistentSet((Map) persistentCollection.getStoredSnapshot());
            }
            return persistentCollection.getStoredSnapshot();
        }
    
        private static  Set unproxyPersistentSet(Map persistenceSet) {
            return new LinkedHashSet(persistenceSet.keySet());
        }
    
    }
    
    
    

    I use this function over result of my RPC services (via aspects) and it cleans recursively all result objects from proxies (if they are not initialized).

    提交回复
    热议问题