Hi
No worries, here is the code, as I said it was developed by someone else, I just modified it to ensure that if the mian object is a collection that it checks for Persistent collections inside it.
Code:
/**
* Eliminate any reference to the Hibernate persistent collections.
*
* @param bean object to process
*/
public void processHibernatedBean(final Object bean, final Session session) {
Class type = bean.getClass();
if (Collection.class.isAssignableFrom(type) ) {
for(Object object : ((Collection)bean)) {
processHibernatedBean(object, new HashSet(), session);
}
} else {
processHibernatedBean(bean, new HashSet(), session);
}
}
private void processHibernatedBean(final Object bean, final Set processed, final Session session) {
if (processed.contains(bean)) {
return;
} else {
try {
session.evict(bean);
} catch (HibernateException e) {
getLog().warn("Error in session.evict", e);
}
processed.add(bean);
}
final BeanInfo beanInfo = getBeanInfo(bean.getClass());
if (beanInfo == null) {
return;
}
final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
final PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
final Class type = propertyDescriptor.getPropertyType();
Object value;
try {
value = propertyDescriptor.getReadMethod().invoke(bean, new Object[0]);
} catch (Exception e) {
getLog().warn("Error reader property " + propertyDescriptor.getDisplayName(), e);
value = null;
}
if (value != null) {
final Class clazz = value.getClass();
if ((Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))
&& clazz.getName().startsWith("org.hibernate")) {
final Object newValue;
final boolean inicialitzat = Hibernate.isInitialized(value);
switch (getCollectionType(clazz)) {
case TYPE_LIST:
newValue = inicialitzat ? new LinkedList<Object>((Collection) value) : Collections.EMPTY_LIST;
break;
case TYPE_SET:
newValue = inicialitzat ? new HashSet<Object>((Collection<Object>) value) : Collections.EMPTY_SET;
break;
case TYPE_MAP:
newValue = inicialitzat ? new HashMap<Object,Object>((Map<Object,Object>) value) : Collections.EMPTY_MAP;
break;
default:
getLog().info("Tipus desconegut? " + clazz.getName());
newValue = null;
break;
}
try {
if (getLog().isDebugEnabled()) {
getLog().debug("|---Replaced with --------->" + newValue.getClass().getName());
}
propertyDescriptor.getWriteMethod().invoke(bean, new Object[] { newValue });
} catch (Exception e) {
getLog().warn("Error changing property", e);
}
if (inicialitzat) {
Collection values = Collection.class.isAssignableFrom(type) ? (Collection) newValue
: ((Map) newValue).values();
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
final Object o = iterator.next();
if (o != null) {
if (ValueObject.class.isAssignableFrom(o.getClass())) {
processHibernatedBean(o, processed, session);
}
}
}
}
} else {
if (ValueObject.class.isAssignableFrom(type)) {
if (Hibernate.isInitialized(value)) {
processHibernatedBean(value, processed, session);
} else {
Object newValue = null;
try {
Class newClazz = HibernateProxyHelper.getClassWithoutInitializingProxy(value);
newValue = newClazz.newInstance();
ClassMetadata clazzMetaData = session.getSessionFactory().getClassMetadata(newClazz);
Serializable id = clazzMetaData.getIdentifier(value, EntityMode.POJO);
clazzMetaData.setIdentifier(newValue, id, EntityMode.POJO);
} catch (Exception e) {
getLog().warn(
"Error instantiating lazy val:" + value + " newClazz:"
+ newValue.getClass().getName(), e);
}
try {
propertyDescriptor.getWriteMethod().invoke(bean, new Object[] { newValue });
} catch (Exception e) {
getLog().warn("Error finding property write", e);
}
}
}
}
}
}
}
Note that this code was also slightly modified for JDK 1.5 but should work with anything.
So, say you have object myObject to return via RMI you simply call:
processHibernatedBean(myObject, theHibernateSession)
Also, ALL your objects that may contain persistent collections should implement an empty interface "ValueObject".
I have not measured the impact, it is still very fast and it removed a showstopper for me so...
Good luck!
Benoit