Allright; I've got something.  Would love to hear opinions as to whether this 
makes for good design, and I'll probably cross-post this somewhere on the 
Hibernate forums to get thoughts from there...

Given a static utility method (code all below) that will return a non-Hibernate 
Collection of Entities, I had wanted to create a method that would strip out 
all Hibernate Collections from a POJO, like:

Object newPojo = PersistenceUtils.removePersistenceContext(myPojo);

...however, could not figure any intelligent way to instruct the method as to 
how deeply it should be traversing its own graph to look for Hibernate classes.

So I restructured a bit (this is the part on which I'm wavering) to place the 
Hibernate-stripping method in an assumed Base Class for all entities.  So the 
call now looks more like:

myPojo.removePersistenceContext();

I don't like that this solution requires a base entity class.

But it works for now - curious as to anyone's thoughts.

The Utility Class:

public class PersistenceUtils {
  | 
  |     /**
  |      * Returns a Collection of all objects in the specified 
persistentCollection
  |      * without binding to any persistence context or session.
  |      * 
  |      * @param <T>
  |      * @param targetCollection
  |      * @param persistentCollection
  |      * @return
  |      */
  |     public static <T> Collection<T> 
removeCollectionItemsFromPersistenceContext(
  |                     Collection<T> targetCollection, Collection<T> 
persistentCollection) {
  |             // If runtime type of persistentCollection is not 
PersistentCollection,
  |             // take no action
  |             if (!(persistentCollection instanceof PersistentCollection))
  |                     return persistentCollection;
  | 
  |             // Clear existing target
  |             targetCollection.clear();
  | 
  |             // Place all items in persistent collection into target
  |             for (T item : persistentCollection) {
  |                     targetCollection.add(item);
  |             }
  | 
  |             // Return target
  |             return targetCollection;
  |     }
  | 
  | }
  | 


Base Entity Class (from which all EJB3 Entities inherit; relevent code only 
shown):

/**
  |      * Strips the entity of all data binding it to a specific persistence
  |      * context, leaving intact only model-centric data
  |      * 
  |      * @author ALR
  |      */
  |     public void removePersistenceContext() {
  |             // Initialize
  |             Collection<Integer> visitedObjectHashCodes = new 
ArrayList<Integer>();
  | 
  |             // Run
  |             this.removePersistenceContext(this, visitedObjectHashCodes);
  |     }
  | 
  |     /**
  |      * 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
  |      */
  |     private Object removePersistenceContext(Object obj,
  |                     Collection<Integer> visitedObjectHashCodes) {
  | 
  |             // Ensure the current object has not been visited
  |             if 
(visitedObjectHashCodes.contains(System.identityHashCode(obj))) {
  |                     return obj;
  |             }
  | 
  |             // Add the current object's hash to the Collection of visited 
hash codes
  |             visitedObjectHashCodes.add(System.identityHashCode(obj));
  | 
  |             // If the current object is of type Collection
  |             if (Collection.class.isInstance(obj)) {
  |                     // Remove persistence context
  |                     obj = 
PersistenceUtils.removeCollectionItemsFromPersistenceContext(
  |                                     new ArrayList(), (Collection) obj);
  |             }
  | 
  |             // Only traverse into types of PersistedEntity
  |             if (!(PersistedEntity.class.isInstance(obj))) {
  |                     return obj;
  |             }
  | 
  |             // Remove persistence context of all members
  |             Map allMembers = this.getInternalMembers();
  |             for (Object member : allMembers.entrySet()) {
  |                     Map.Entry m = (Map.Entry) member;
  |                     try {
  |                             PropertyUtils.setProperty((Object) obj, 
m.getKey().toString(),
  |                                             
this.removePersistenceContext((m.getValue()),
  |                                                             
visitedObjectHashCodes));
  |                     } catch (IllegalAccessException e) {
  |                             throw new RuntimeException(e);
  |                     } catch (InvocationTargetException e) {
  |                             throw new RuntimeException(e);
  |                     } catch (NoSuchMethodException e) {
  |                     }
  |             }
  | 
  |             // Return
  |             return obj;
  |     }
  | 
  |     // Internal Helper Methods
  |     /**
  |      * 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/
  |      */
  |     protected Map getInternalMembers(PersistedEntity obj) {
  |             try {
  |                     // Return a map of all visible properties
  |                     return PropertyUtils.describe(obj);
  |             }
  |             // Throw as unchecked exceptions up the stack trace
  |             catch (IllegalAccessException iae) {
  |                     throw new RuntimeException(iae);
  |             } catch (NoSuchMethodException nsme) {
  |                     throw new RuntimeException(nsme);
  |             } catch (InvocationTargetException ite) {
  |                     throw new RuntimeException(ite);
  |             }
  |     }
  | 
  |     /**
  |      * Returns a Map of all internal members of this PersistedEntitys
  |      * 
  |      * @author ALR
  |      * @see http://jakarta.apache.org/commons/beanutils/
  |      */
  |     protected Map getInternalMembers() {
  |             return getInternalMembers(this);
  |     }

Easy to use (one line of code), and it works.  But I have the nagging feeling I 
can't be the first to have come across this, and there's a better way?

S,
ALR

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

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3969582
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to