hibernate - Cannot serialize JPA bean due to presence of proxies -
i trying expose object xml using jax-rs.
i have class called client
, returning instance this:
@transactional(readonly=true) @get @produces("application/xml") @path("/{clientid}.xml") public client getcleintasxml(@pathparam("clientid") int clientid) { client c = em.find(client.class, clientid); return c; }
but client
object has list of group
objects , group
object in turn has list of other objects.
when jax-rs tries serialize client
object traverses entire object graph. when ecounters hibernate proxy groups
code breaks because lazy loading works inside transaction.
fair enough, load groups
eagerly before exiting transaction.
but still fails because each group
object in turn has one-to-many relations i.e. more proxied lists.
i don't need them in output. realize problem solved if these proxies removed i.e set null.
i don't want manually set them null error prone , not maintainable. there way automatically?
or can tell hibernate not use proxies particular query? or use proxies 1 level deep?
i using hibernate behind jpa. far possible don't want direct references hibernate.
i found dozen classes written different users rid of proxies. there standard way this? if such common problem, guess, there standard solution.
resolved removing uninitialized hibernate proxies. removes collections requirement. feel free suggest edits benefit of other users.
first cut:
import java.beans.propertydescriptor; import java.lang.reflect.invocationtargetexception; import java.util.collection; import org.apache.commons.beanutils.propertyutils; import org.hibernate.hibernate; import org.hibernate.collection.persistentcollection; import org.springframework.beans.beanutils; public class hibernateproxycleaner { public static object clean(object bean) { return clean(bean,0,2); } public static object clean(collection bean, int depth, int maxdepth) { if (bean == null || depth>maxdepth) return bean; (object o : (collection) bean) { clean(o,depth,maxdepth); } return bean; } public static object clean(object bean, int depth, int maxdepth) { if (bean == null || depth>maxdepth) return bean; try { propertydescriptor[] pda = beanutils.getpropertydescriptors(bean .getclass()); (propertydescriptor pd : pda) { object o = propertyutils.getproperty(bean, pd.getname()); if (o != null) { if (o instanceof persistentcollection) { if (propertyutils.isreadable(bean, pd.getname()) && propertyutils.iswriteable(bean, pd.getname())) { if (!hibernate.isinitialized((persistentcollection) o)) { o = null; propertyutils.setproperty(bean, pd.getname(), o); } } } else { clean(o,depth+1,maxdepth); } } } } catch (illegalaccessexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (invocationtargetexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (nosuchmethodexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); } return bean; } }
Comments
Post a Comment