> Hi Asi
>
> The problem with Hibernate and GWT is that Hibernate needs to return
> Hibernate proxy classes so it can detect changes made to your objects and
> detect access to associations that are not loaded. The problem with this
> mechanism is that when you try to serialize your classes through GWT-RPC it
> will break throwing LazyInitializationException. So the solutions is to get
> rid of those proxy classes. One way that I've seen recommended in the GWT
> group is to create another object and copy the information. This will work
> but you will have to code a lot to make this work when your object graph is
> big. The solution that I have found is to clean the proxies using a
> HibernateCleaner class:
>
> import java.beans.PropertyDescriptor;
>
> import java.io.InputStream;
>
> import java.util.ArrayList;
> import java.util.Date;
> import java.util.HashMap;
> import java.util.HashSet;
> import java.util.Map;
> import java.util.Set;
> import java.util.List;
>
> import org.apache.commons.beanutils.PropertyUtils;
>
> import org.hibernate.EntityMode;
> import org.hibernate.Hibernate;
> import org.hibernate.Session;
> import org.hibernate.metadata.ClassMetadata;
> import org.hibernate.proxy.HibernateProxyHelper;
>
> import java.io.Serializable;
>
> import java.sql.Blob;
>
> import java.util.*;
>
> import org.apache.log4j.Logger;
>
> import org.hibernate.proxy.HibernateProxy;
>
> public class HibernateCleaner {
>     private static final Logger logger =
> Logger.getLogger(HibernateCleaner.class);
>
>     public static Object clean(Session session, Object obj) throws
> Exception {
>         return (clean(session, obj, new HashMap<Class, Map<Object,
> Object>>()));
>     }
>
>     private static Object clean(Session session,
>                                 Object obj,
>                                 Map<Class, Map<Object, Object>>
> visitedObjects) throws Exception {
>         Object newObj, value = null, cleanValue = null;
>         Map.Entry m;
>         Class clazz;
>         Object[] array;
>         Collection collection;
>         Map map;
>         PropertyDescriptor[] descriptors;
>         String property;
>         ClassMetadata clazzMetaData;
>         Map<Object, Object> visitedObjectsInClass;
>         int index, length, hashCode;
>
>         if (obj == null)
>             return (null);
>
>         if ((obj instanceof Boolean) || (obj instanceof Number) ||
>             (obj instanceof Character) || (obj instanceof String) ||
>             (obj instanceof Blob) || (obj instanceof InputStream))
>             return (obj);
>
>         if (obj instanceof Date)
>             return (new Date (((Date) obj).getTime()));
>
>         if (obj instanceof Calendar)
>             return (((Calendar) obj).clone());
>
>         if (obj instanceof Object[]) {
>             array = (Object[]) ((Object[]) obj).clone();
>             length = array.length;
>             for (index = 0; index < length; index++)
>                 array[index] = clean(session, array[index],
> visitedObjects);
>
>             return (array);
>         }
>
>         if (obj instanceof Object[]) {
>             array = (Object[]) ((Object[]) obj).clone();
>             length = array.length;
>             for (index = 0; index < length; index++)
>                 array[index] = clean(session, array[index],
> visitedObjects);
>
>             return (array);
>         }
>
>         if (obj instanceof Collection) {
>             collection = createCollection((Collection) obj);
>
>             if (Hibernate.isInitialized(obj)) {
>                 for (Object member: (Collection) obj)
>                     collection.add (clean(session, member,
> visitedObjects));
>             }
>
>             return (collection);
>         }
>
>         if (obj instanceof Map) {
>             map = createMap((Map) obj);
>
>             if (Hibernate.isInitialized(obj)) {
>                 for (Object member: ((Map)obj).entrySet()) {
>                     m = (Map.Entry) member;
>                     clean(session, m.getKey(), visitedObjects);
>                     clean(session, m.getValue(), visitedObjects);
>                     map.put (m.getKey(), m.getValue());
>                 }
>             }
>
>             return (map);
>         }
>
>         if (obj instanceof HibernateProxy) {
>             clazz =
> HibernateProxyHelper.getClassWithoutInitializingProxy(obj);
>         } else {
>             clazz = obj.getClass();
>         }
>
>         visitedObjectsInClass = visitedObjects.get(clazz);
>         if (visitedObjectsInClass == null) {
>             visitedObjectsInClass = new HashMap<Object, Object>();
>             visitedObjects.put(clazz, visitedObjectsInClass);
>         } else if (visitedObjectsInClass.containsKey(obj)) {
>             return visitedObjectsInClass.get(obj);
>         }
>
>         newObj = clazz.newInstance();
>         visitedObjectsInClass.put(obj, newObj);
>
>         if (!Hibernate.isInitialized(obj)) {
>             if (session != null) {
>                 clazzMetaData =
> session.getSessionFactory().getClassMetadata(newObj.getClass());
>                 Serializable id = clazzMetaData.getIdentifier(obj,
> EntityMode.POJO);
>                 clazzMetaData.setIdentifier(newObj, id, EntityMode.POJO);
>             }
>         } else {
>             descriptors = PropertyUtils.getPropertyDescriptors(newObj);
>             length = descriptors.length;
>             for (index = 0; index < length; index++) {
>                 property = descriptors[index].getName();
>                 if (!property.equals("class")) {
>                     try {
>                         value = PropertyUtils.getProperty(obj, property);
>                         cleanValue = clean(session, value, visitedObjects);
>                         PropertyUtils.setProperty(newObj, property,
> cleanValue);
>                     } catch (NoSuchMethodException e) {
>                     } catch (Exception e) {
>                         if (logger.isInfoEnabled()) logger.info("Error
> Clean: " + obj.getClass() + " - " + property + " - " + value.getClass() + "
> - " + cleanValue.getClass());
>                         throw(e);
>                     }
>                 }
>             }
>         }
>
>         return (newObj);
>     }
>
>     private static Collection createCollection(Collection obj) throws
> Exception {
>         Collection newObj = null;
>
>         if (obj instanceof SortedSet)
>             newObj = new TreeSet ();
>         else if (obj instanceof Set)
>             newObj = new HashSet ();
>         else
>             newObj = new ArrayList ();
>
>         return (newObj);
>     }
>
>     private static Map createMap(Map obj) throws Exception {
>         Map newObj = null;
>
>         if (obj instanceof SortedMap)
>             newObj = new TreeMap ();
>         else
>             newObj = new HashMap ();
>
>         return (newObj);
>     }
> }
>
> I've used this class in many production applications and it works.
>
> Regards,
>
> Néstor Boscán
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to