Hibernate 延迟初始化帮助
我在尝试使用休眠删除时遇到问题。当我尝试删除时,出现异常,提示存在子项并且存在 FK 违规。我也想删除孩子们,但删除似乎不是级联的。经过大约一周的尝试解决此问题后,我了解到我应该使用 HibernateInterceptor 来保持会话打开,以便可以加载子级。当我现在尝试执行此操作时,出现以下错误:
Failed to load portlet com.blah.blah.CommunicationsPortlet: java.lang.ClassCastException: $Proxy27 incompatible with com.blah.blah.HibernateCommunicationsDAOImpl
这是我的映射文件的摘录:
<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>
这是应用程序上下文的摘录:
<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>
这是我的 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 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您只想删除父级和子级,则无需加载子级集合。您甚至不需要
get()
父级,使用load()
就足够了:当然,这假设适当的映射/级联到位。设置您显示的映射摘录是可以的,但
设置除外。由于以下几个原因,它相当棘手:因此,我建议暂时删除
on-delete="cascade"
并且在您完全理解所有含义之前不要使用它。您提到的 HibernateInterceptor 与所有这些无关(最肯定与您编码的 delete() 方法无关);它是与 UI 层通信的 open-session-in-view 方法的一部分。
以下是解决上述所有问题的方法:
Communication
实例并覆盖其communicationCountries
集合。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:
Communication
instance and overwriting itscommunicationCountries
collection.