Hibernate(JPA)级联 - 从子级检索id

时间:2010-02-01 15:38:51

标签: hibernate orm jpa

我有一个父类,其中包含以下带有级联选项的字段:

public class Parent {
  @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
  @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
  private final Set<Child> children = new HashSet<Child>();
  public addChild(Child child) { children.add(child); }
}

在我的应用程序中,我想添加一个子项,然后在父类上调用JPA merge,自动保持我的新子项。这一切都有效,但是,我插入到父对象中的原始子引用已更改,这意味着我无法检索持久子代的ID。有什么方法可以告诉hibernate重新使用我的旧子引用而不是创建一个新的引用吗?在合并期间

2 个答案:

答案 0 :(得分:1)

只需获取父级的合并实例:

parent = entityManager.merge(parent);

更新:

你想要的是不可能的。手动merge()子项,然后将其添加到父项,或者从父集合中获取新的子项实例并使用它。

答案 1 :(得分:1)

对于许多动作,Hibernate生成一个可以监听的事件和一些支持代码用于监听。

例如,如果你将Spring与Hibernate结合使用,你可以注册一个类org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener作为hibernate合并事件的监听器(来自我认为spring-orm.jar)将以下内容放在你的hibernate.cfg.xml中(或者你的spring设置中为hibernate配置引用的任何文件):

    <event type="merge">
        <listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
    </event>

或在sessionFactory bean中添加一个地图:

    <bean id="sessionFactory" 
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
          p:dataSource-ref="dataSource">
    <property name="configLocation" value="WEB-INF/classes/hibernate.cfg.xml"/>
    <property name="eventListeners">
            <map>
                    <entry key="merge">
                            <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
                    </entry>
            </map>
    </property>

如果您执行其中任何一项操作,此侦听器应在原始对象中设置id。如果你没有使用Spring,那么很可能有一种方法可以让听众连接类似于其中一个。

我还没有测试过您正在寻找的子行为,但我很确定父项上的合并会触发子项上的合并,以便为两者调用侦听器。

JPA的设置可能有所不同,但我怀疑这是可能的,希望这能提供线索。