Hibernate - 如何在分离的对象上级联删除

时间:2009-08-11 19:40:46

标签: java hibernate

我有一个hibernate对象,它被分离并转移到使用EJB的胖java swing客户端。然后以某种方式修改对象并返回到服务器,然后服务器将修改后的对象更新到数据库。一切都适用于更改的属性,但我在如何删除many-to-one映射时遇到问题。

例如,给定以下映射:

<hibernate-mapping>
<class name="com.wg.common.bean.Patient" table="patient">
    <id name="id" type="integer">
        <column name="id" />
        <generator class="sequence">
            <param name="sequence">patient_id_seq</param>
        </generator>
    </id>
    <many-to-one name="address" class="com.wg.common.bean.Address" cascade="all">
        <column name="address_id" />
    </many-to-one>
    ...

说我有一个发送给客户的患者对象。用户先前已添加地址。每位患者只能有一个地址。在客户端上,如果用户删除了地址,我会在患者对象上调用setAddress(null),然后再返回服务器。当我到达服务器时,它将address_id字段保存为null,但将地址记录保留在数据库中。我明白为什么这样做。我只打破了这段关系的一端。我最好使用delete-orphan。但是,根据Hibernate文档,delete-orphan不适用于many-to-one映射。正确的程序是调用服务器(伪代码):

Address address = patient.getAddress();
session.delete(address);
patient.setAddress(null);

这种模式的问题在于,如果我想坚持简单地传回我想保存的Patient对象的过程,我无法知道它是否有需要删除的地址。我必须做一些不那么优雅的解决方法来解决这个问题,例如查询数据库以查看是否存在地址并在传递的对象中为null时删除它,或者创建setDeleteAddress(boolean),{{ 1}} Patient类中的方法,如果用户想要删除地址,则在客户端设置这些方法。

另一种选择是使患者和地址之间的关联成为一对多。然后我可以使用getDeleteAddress()。但是,因为它实际上是一对一的关系,所以我需要在Patient类中放置一些疯狂的getter / setter,这样我就不会在没有集合的情况下使用集合引用丢弃我的代码:

delete-orphan

有没有更好的方法来解决这个问题?你是如何处理在分离对象上删除实体的?

3 个答案:

答案 0 :(得分:0)

映射地址many-to-one似乎是您问题的根源。地址是这种关系中的“父母”,这没有多大意义。考虑将其映射为组件或一对一映射。无论如何都不应该涉及任何收集。

答案 1 :(得分:0)

我似乎记得在某些情况下,实际上可以将单一属性映射为单一属性。我无法验证这一点,但documentation中有一些提示。

  

或者,具有唯一约束的外键(从Employee到Person)可表示为:

<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>
  

通过在Person映射中添加以下内容,可以使此关联成为双向:

<one-to-one name="employee" class="Employee" property-ref="person"/>

您可能需要稍微摆弄一下,并将cascade="delete"添加到一对一映射中。我自己从未尝试过这个。如果您可以控制数据库架构,那么最好的选择是ChssPly76的答案。

答案 2 :(得分:0)

我最后只是在deleteFlag类中创建了一个Address,以便向EJB指定应该从Address中删除有问题的Patient