> 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.