[jboss-user] [EJB 3.0] - Re: Detach entities - Obtaining a clear pojo

fatbatman do-not-reply at jboss.com
Wed Sep 6 21:07:34 EDT 2006


Actually I think a better implementation is that included below;
it should certain perform  much better as it now gets the inner hibernate collection object rather than creating a new object to replicate it.
Note - the package name so we can get the inner collection.
 
It still needs further testing, as I'm aware of couple of issues which I'll look at tomorrow

package org.hibernate.collection;
  | 
  | import java.lang.annotation.Annotation;
  | import java.lang.reflect.InvocationTargetException;
  | import java.util.ArrayList;
  | import java.util.Collection;
  | import java.util.Map;
  | 
  | import javax.persistence.Entity;
  | 
  | import org.apache.commons.beanutils.PropertyUtils;
  | import org.hibernate.LazyInitializationException;
  | 
  | /**
  |  * Some utils methods to get a complete clean POJO from an entity bean with hibernate specific fields stripped out.
  |  * Note this class is not meant as a way of avoid LazyInitializationException's.  Its purpose to strip out data before sending the object
  |  * to remote client so that does not have knowledge of hibernate classes. 
  |  * @author ALR 5/9/2006
  |  * @author modified by James Adams 6/9/2006, 7/9/2006
  |  *
  |  */
  | public class HibernateCleaner {
  | 
  | 	public static Object clean(Object obj){
  | 		return removePersistenceContext(obj, new ArrayList<Integer>(), 0);
  | 	}
  | 	
  | 	/**
  | 	 * Checks if the object is an Entity bean by searching for the presence of 
  | 	 * the @Entity tag in the objects class.
  | 	 * NOTE - If you are not using annotations to define your entity objects this function will not work
  | 	 * and require an alternative implementation.
  | 	 * @author James Adams
  | 	 */
  | 	public static boolean isEntityBean(Object obj){
  | 		for(Annotation a : obj.getClass().getAnnotations()){	
  | 			if(a.annotationType()==Entity.class){
  | 				return true;
  | 			}			
  | 		}		
  | 		return false;
  | 	}
  | 	
  | 
  | 	/**
  | 	 * If the specified object's identity hash code is not in the specified
  | 	 * collection of visited hash codes, removes of all data binding the object
  | 	 * (and its members) to a specific persistence context, leaving intact only
  | 	 * model-centric data
  | 	 * 
  | 	 * @param visitedObjectHashCodes
  | 	 * @param obj
  | 	 * @author ALR
  | 	 * @author James Adams, modified 6/9/2006,7/9/2006
  | 	 */
  | 	private static Object removePersistenceContext(Object obj, Collection<Integer> visitedObjectHashCodes, int traverseLayer ){
  | 		if(obj==null){
  | 			return null;
  | 		}
  | 
  | 		if(visitedObjectHashCodes.contains(System.identityHashCode(obj))){
  | 			return obj;
  | 		}
  | 		
  | 		//Add the object's hash to the Collection of visited hash codes
  | 		visitedObjectHashCodes.add(System.identityHashCode(obj));
  | 
  | 		try{			
  | 			// If runtime type of persistentCollection is PersistentCollection get the inner collection
  | 			if ((obj instanceof PersistentCollection))				
  | 				obj = getInnerCollection((PersistentCollection)obj);
  | 		}catch(LazyInitializationException e){
  | 			return null;		
  | 		}
  | 		
  | 		if(obj==null){
  | 			return null;
  | 		}
  | 		
  | 		//We always check all properties in the top layer object.
  | 		if(traverseLayer>0 && !isEntityBean(obj) ){
  | 			return obj;
  | 		}		
  | 		
  | 		Map allMembers = getInternalMembers(obj);
  | 		for(Object member : allMembers.entrySet()){
  | 			Map.Entry m = (Map.Entry)member;
  | 			try {
  | 				try{
  | 					PropertyUtils.setProperty(obj, m.getKey().toString(), removePersistenceContext(m.getValue(), visitedObjectHashCodes, traverseLayer+1));			
  | 				}catch (LazyInitializationException e){
  | 					PropertyUtils.setProperty(obj, m.getKey().toString(), null);
  | 				}
  | 			} catch (IllegalAccessException e) {
  | 				throw new RuntimeException(e);
  | 			} catch (InvocationTargetException e) {
  | 				throw new RuntimeException(e);
  | 			} catch (NoSuchMethodException e) {				
  | 			}
  | 		}
  | 		
  | 		return obj;
  | 	}
  | 	
  | 	/**
  | 	 * Because this class is in package org.hibernate.collection this method
  | 	 * allows us to access the inner protected fields of the hibernate collections
  | 	 * @param obj
  | 	 * @return The inner collection object of the PersistentCollection parameter
  | 	 * @author James Adams
  | 	 */
  | 	protected static Object getInnerCollection(PersistentCollection obj){
  | 		if(obj instanceof PersistentBag){
  | 			return ((PersistentBag)obj).bag;
  | 		}else if(obj instanceof PersistentList){
  | 			return ((PersistentList)obj).list;			
  | 		}else if(obj instanceof PersistentSet){
  | 			return ((PersistentSet)obj).set;			
  | 		}else if(obj instanceof PersistentMap){
  | 			return ((PersistentMap)obj).map;			
  | 		}else if(obj instanceof PersistentSortedMap){
  | 			return ((PersistentSortedMap)obj).map;			
  | 		}else if(obj instanceof PersistentSortedSet){
  | 			return ((PersistentSortedSet)obj).set;			
  | 		}else{
  | 			return null;
  | 		}		
  | 	}	
  | 	
  | 	
  | 	/**
  | 	 * Returns a Map of all internal members of the specified object
  | 	 * 
  | 	 * @param obj
  | 	 *            The object for which to obtain internal members
  | 	 * 
  | 	 * @author ALR
  | 	 * @see http://jakarta.apache.org/commons/beanutils/
  | 	 */
  | 	private static Map getInternalMembers(Object obj){
  | 		try {
  | 			Map map = PropertyUtils.describe(obj);
  | 			return map;
  | 		} catch (IllegalAccessException e) {
  | 			throw new RuntimeException(e);
  | 		} catch (InvocationTargetException e) {
  | 			throw new RuntimeException(e);
  | 		} catch (NoSuchMethodException e) {
  | 			throw new RuntimeException(e);
  | 		}		
  | 	}
  | 	
  | }
  | 


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3969926#3969926

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3969926



More information about the jboss-user mailing list