[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