PDA

View Full Version : Storing Proxy into Hibernate



davidwery
Oct 13th, 2004, 11:09 AM
Hi all !

When I try to store a Proxy (created by the ProxyFactoryBean) into Hibernate, I have the following exception :

Exception in thread "main" org.springframework.orm.hibernate.HibernateSystemE xception: No persister for: $Proxy0; nested exception is net.sf.hibernate.MappingException: No persister for: $Proxy0
net.sf.hibernate.MappingException: No persister for: $Proxy0
at net.sf.hibernate.impl.SessionFactoryImpl.getPersis ter(SessionFactoryImpl.java:347)
at net.sf.hibernate.impl.SessionImpl.getClassPersiste r(SessionImpl.java:2690)
at net.sf.hibernate.impl.SessionImpl.getPersister(Ses sionImpl.java:2697)
at net.sf.hibernate.impl.SessionImpl.saveWithGenerate dIdentifier(SessionImpl.java:763)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl .java:738)
at product.CompanyDAOImpl.add(CompanyDAOImpl.java:154 )

The code in my DAO is :

public void add(final Company company) throws DAOException {
final Session session;

session = SessionFactoryUtils.getSession(getSessionFactory() , false);
try {
session.save(company);
} catch (HibernateException ex) {
throw SessionFactoryUtils.convertHibernateAccessExceptio n(ex);
}
}

My application-context.xml looks like :

<bean id="companyImpl" class="product.CompanyImpl"/>

<bean id="company" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>product.Company</value>
</property>
<property name="target">
<ref local="companyImpl"/>
</property>
</bean>

<bean id="companyDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>product.CompanyDAO</value>
</property>
<property name="interceptorNames">
<list>
<value>myHibernateInterceptor</value>
<value>companyDaoImpl</value>
</list>
</property>
</bean>

Any idea ?

Thanks...

Rod Johnson
Oct 14th, 2004, 04:41 AM
In Hibernate 2 I don't think there's a way to persist a proxy, given that Hibernate depends on the class name. I believe this changes in Hibernate 3 (but of course that doesn't help you much right now).

So you'll have to work around it. You could probably easily change your save method to unwrap the target and save it if the target is advised. Something like:


Object target = o;
if &#40;o instanceof Advised&#41; &#123;
TargetSource ts = &#40;&#40;Advised&#41; o&#41;.getTargetSource&#40;&#41;;
// Probably can't handle fancier target sources,
// but probably doesn't matter so you can just add
// a check and throw UnsupportedOperationException
target = &#40;&#40;SingletonTargetSource&#41; ts&#41;.getTarget&#40;&#41;;
&#125;
template.save&#40;target&#41;;

I haven't tried this, but I think it would work.

A generic save method could do this easily enough for any advised (or non-advised) object.

davidwery
Oct 22nd, 2004, 09:44 AM
Thanks, it works fine !

But I have another problem while storing Proxy into Hibernate. How can I store Proxy with other Proxy fields ? For example, storing a Company Proxy which have a reference to an Employee Proxy :

public class Company {
private Employee employee; // Employee which is a Proxy

public Employee getEmployee() {
return employee;
}

....
}

So, the storing of the Company works fine without the Employee by doing the procedure seen above, but crash with the Employee :

apple.awt.EventQueueExceptionHandler Caught Throwable : org.springframework.orm.hibernate.HibernateSystemE xception: No persister for: $Proxy2; nested exception is net.sf.hibernate.MappingException: No persister for: $Proxy2
org.springframework.orm.hibernate.HibernateSystemE xception: No persister for: $Proxy2; nested exception is net.sf.hibernate.MappingException: No persister for: $Proxy2
net.sf.hibernate.MappingException: No persister for: $Proxy2

Rod Johnson
Nov 2nd, 2004, 03:22 AM
Mmmm, you could write something that walked the object graph and replaced references to proxies with references to the target (as in the code above). Can't think of too many other solutions.