I have an issue trying to delete using hibernate. When I try to delete I get an exception saying that children exist and there is a FK violation. I want to delete the children also but the delete doesn’t seem to be cascading. After about a week of trying to fix this issue I read that I should be using HibernateInterceptor to keep the session open so that the children can be loaded. When I try to do this now I get the following error:
Failed to load portlet com.blah.blah.CommunicationsPortlet: java.lang.ClassCastException: $Proxy27 incompatible with com.blah.blah.HibernateCommunicationsDAOImpl
Here is the extract from my mapping file:
<set name="communicationCountries" inverse="true" cascade="all,delete-orphan">
<key column="COM_ID" not-null="true" on-delete="cascade" />
<one-to-many class="com.blah.blah.CommunicationCountry"/>
</set>
Here is an extract from the application context:
<bean id="hibernateCommunicationsDAOImplTarget"
class="com.blah.blah.dao.impl.HibernateCommunicationsDAOImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="hibernateCommunicationsDAOImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><ref bean="hibernateCommunicationsDAOImplTarget"/></property>
<property name="proxyInterfaces">
<value>com.blah.blah.dao.CommunicationsDAO</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
Here is the method in my DAO:
public void deleteCommunication(Integer id) throws DataAccessException
{
HibernateTemplate hibernate = getHibernateTemplate();
Communication existing = (Communication)hibernate.get(Communication.class, id);
hibernate.initialize( existing.getCommunicationCountries());
hibernate.delete(existing);
}
I really don’t know what I am doing wrong. I do not have a very complex schema, just one table that results in children (countries). Any ideas what I could do to fix this?
If you simply want to delete parent along with children, you do NOT need to load the children collection. You don’t even need to
get()the parent, usingload()is enough:This, of course, assumes the appropriate mapping / cascade in place. Set mapping excerpt you’ve shown is OK with exception of
<key ... on-delete="cascade"/>setting. It’s rather tricky for several reasons:I would therefore suggest to remove
on-delete="cascade"for now and to not use it in general until you completely understand all the implications.HibernateInterceptor you’ve mentioned has nothing to do with all of this (most certainly not with the delete() method as you have it coded); it’s part of open-session-in-view approach to communication with UI layer.
Here’s how to troubleshoot all of the above:
Communicationinstance and overwriting itscommunicationCountriescollection.