Hibernate (JPA) каскад - получить идентификатор от дочернего - PullRequest
7 голосов
/ 01 февраля 2010

У меня есть родительский класс со следующим полем с опцией каскадирования:

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 для родительского класса, автоматически сохраняя моего нового дочернего элемента. Это все работает, однако оригинальная дочерняя ссылка, которую я вставил в родительский объект, изменилась, что означает, что я не могу получить идентификатор моего сохраненного потомка. Можно ли как-то сказать hibernate повторно использовать мою старую дочернюю ссылку вместо новой? во время слияния

Ответы [ 2 ]

1 голос
/ 01 февраля 2010

Для многих действий Hibernate генерирует событие, которое можно прослушивать, и некоторый код поддержки для прослушивания.

Если вы используете Spring вместе с Hibernate, например, вы можете зарегистрировать класс org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener в качестве прослушивателя события слияния hibernate (из, я думаю, Spring-orm.jar) добавив в файл hibernate.cfg.xml следующее (или любой другой файл, на который есть ссылка в вашей весенней установке для конфигурации hibernate):

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

или добавив карту в ваш сессионный компонент:

    <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>

Если вы выполните одно из этих действий, этот слушатель должен установить идентификатор в исходном объекте. Если вы не используете Spring, вероятно, есть способ подключить слушателя, который похож на один из них.

Я не проверял искомое поведение, которое вы ищете, но я уверен, что слияние с родителем вызовет слияние с дочерним, так что слушатель будет вызываться для обоих.

Настройки для JPA могут отличаться, но я подозреваю, что это возможно, и надеюсь, что это дает подсказки.

1 голос
/ 01 февраля 2010

Просто получите объединенный экземпляр вашего родителя:

parent = entityManager.merge(parent);

Обновление:

То, что вы хотите, не возможно. Либо вручную merge() дочерний, а затем добавьте его к родительскому, либо получите новый дочерний экземпляр из родительской коллекции и используйте его вместо этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...