2009-09-17 131 views
1

我遇到了一个问题,我试图在Hibernate中进行删除操作。每次我尝试删除时,由于存在子记录,我得到一个问题,因此无法删除父项。我想删除孩子和父母。这里是我的父映射:休眠级联删除不起作用

<set name="communicationCountries" inverse="true" cascade="all,delete-orphan"> 
     <key column="COM_ID" not-null="true" on-delete="cascade" /> 
     <one-to-many class="com.fmr.fc.portlet.communications.vo.CommunicationCountry"/> 
</set> 

这里是子类的映射:

<many-to-one name="communication" column="COM_ID" not-null="true" class="com.fmr.fc.portlet.communications.vo.Communication" cascade="all"/> 

编辑 - 当我插入的数据插入到家长和孩子。

当我使用一个新的对象的ID与对象的ID进行更新时,我想要修改父级更新,但是第二次添加任何现有的子级。我似乎无法删除孩子。当我使用ID检索一个对象并修改它时,我得到一个错误告诉我org.hibernate.LazyInitializationException:无法初始化代理 - 拥有的Session被关闭。我怀疑这是因为在一个getHibernateTemplate()调用中,我得到的对象,我将它保存在另一个,这是两个不同的会话?

当我做删除时,我得到一个错误,因为孩子存在。我知道我只是在做一些愚蠢的事情,因为缺乏对这一切如何运作的线索。

这里是我的更新和删除方法,在这种情况下,更新/保存是在保存前检索和修改。删除使用新的对象具有相同ID作为一个在DB我想删除:

public void deleteCommunication(Communication comm) throws DataAccessException 
{ 
    getHibernateTemplate().delete(comm); 
} 

public void saveCommunication(Communication comm) throws DataAccessException 
{  
    Communication existing = (Communication)getHibernateTemplate().load(Communication.class, comm.getComId()); 
    existing.getCommunicationCountries().clear(); 

    getHibernateTemplate().saveOrUpdate(existing);  
} 

UPDATE 因此,这里有我的新方法,但仍然没有喜悦。我认为我的问题与未加载/初始化等的儿童有关。虽然删除,但我不明白为什么没有发生级联删除。

非常感谢您的帮助。我已经达到了我对这项工作已经截止,所以如果我不把它固定在周末我只是将不得不求助于执行HQL查询,因为我知道,会为我工作:(

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); 
    } 

    public void updateCommunication(Communication comm) throws DataAccessException 
    {  
     HibernateTemplate hibernate = getHibernateTemplate(); 
     Communication existing = (Communication)hibernate.get(Communication.class, comm.getComId()); 
     hibernate.initialize(existing.getCommunicationCountries()); 
     existing.getCommunicationCountries().clear(); 
     hibernate.saveOrUpdate(existing);  
    } 
+0

你可以添加hibernate映射吗?你有没有为关系指定级联? – 2009-09-17 15:34:22

+0

'all,delete-orphan'不是级联标识符。 'all-delete-orphan'是。 – Jherico 2009-09-17 17:54:40

+0

@Jherico - 两者完全一样:http://docs.jboss.org/hibernate/stable/core/reference/en/html/collections.html#collections-mapping。 “all”和“delete-orphan”是有效的级联操作,可以用逗号分隔多个值。 – ChssPly76 2009-09-17 18:23:07

回答

2

在没有特定的顺序:

A)在你的代码假设“身份识别码”是你的实体的标识,你应该用session.get(),而不是标准 - 它的速度更快,最肯定更容易:

MyObject obj = (MyObject) session.get(MyObject.class, new Long(1)); 

B)如果您使用的是Spring(通过getHibernateTemplate()调用来判断),您应该始终如一地使用它:-)而不是直接调用会话,除非绝对必要 - 而且几乎没有必要。因此,上述get方法将成为:

MyObject obj = (MyObject) getHibernateTemplate().get(MyObject.class, new Long(1)); 

如果你需要编写一个基于标准的查询,你可以使用DetachedCriteriaHibernateTemplate.getByCriteria()方法:

DetachedCriteria crit = DetachedCriteria.forClass(MyObject.class) 
.add(Property.forName("myId").eq(new Long(1))); 
List results = getHibernateTemplate().findByCriteria(crit); 

C)通常你不应该evict()对象从会议开始(在结束之前立即进行是毫无意义的)。您通常也不应该从HibernateTemplate获得的会话。

d)最后,至于自动保存孩子(一个一对多的集合元素)去 - 看看this example它提供了不同梯级设置一个很好的解释。如果你仍然有问题,请发布你的映射/代码。

更新(基于问题的澄清):

1)你的映射看起来除了在子类(<many-to-one name="communication" cascade="all"/>)母公司级联确定。你很可能不想要这个。

2)LazyInitializationException被抛出,因为默认情况下Hibernate将集合映射为懒惰,这意味着子项(通讯国家)将不会被加载,直到第一次访问。如果在会话已关闭时发生访问,则会引发异常。您可以通过致电Hibernate.initialize()收集来确保集合已填充。 3)你的delete()应该可以很好地工作正如你在Hibernate返回的实体实例上调用它,而不是你自己创建的那个(比如远程调用解组)的“communicationCountries”集合是没有填充。为了让Hibernate删除孩子,需要知道他们存在。

4)另一方面,您的更新()是错误的。你正在加载一个实体,清除它的子元素,然后再次保存 - 这本身就很好 - 但是没有连接到传入的参数。

+0

感谢您的详细回复。你也喜欢的例子实际上是我正在使用的例子,但我怀疑我只是不明白发生了什么。 所以,如果我想更新一个对象,我可以创建一个具有相同ID的新对象并保存它。当我这样做时,对象被更新,但如果我原本有两个孩子,我又添加了一个,我最终有5个,其中2个是重复的。另外,如果我从集合中删除所有孩子,则在数据库中都不会删除任何孩子。 我有同样的问题删除父,级联删除的孩子没有发生,所以我得到一个异常。 – Caroline 2009-09-17 21:23:00

+0

在主要问题中增加了更多详细信息.... – Caroline 2009-09-17 21:47:18

+0

如果您想**更新**一个对象,那么您肯定无法**创建**具有相同ID的新对象。那么,你可以在理论上使用'merge()',但我会强烈建议反对它,直到你明确地知道你在做什么。 – ChssPly76 2009-09-17 21:51:04