JPA каскадное удаление: установка дочернего FK в NULL для столбца NOT NULL - PullRequest
2 голосов
/ 23 апреля 2010

У меня есть две таблицы: t_promo_program и t_promo_program_param.

Они представлены следующими объектами JPA:

@Entity
@Table(name = "t_promo_program")
public class PromoProgram {
  @Id
  @Column(name = "promo_program_id")
  private Long id;

  @OneToMany(cascade = {CascadeType.REMOVE})
  @JoinColumn(name = "promo_program_id")
  private List<PromoProgramParam> params;
}

@Entity
@Table(name = "t_promo_program_param") 
public class PromoProgramParam {
  @Id
  @Column(name = "promo_program_param_id")
  private Long id;

  //@NotNull // This is a Hibernate annotation so that my test db gets created with the NOT NULL attribute, I'm not married to this annotation.
  @ManyToOne
  @JoinColumn(name = "PROMO_PROGRAM_ID", referencedColumnName = "promo_program_id")
  private PromoProgram promoProgram;
}

Когда я удаляю PromoProgram, Hibernate обращается к моей базе данных с помощью:

update
    T_PROMO_PROGRAM_PARAM 
set
    promo_program_id=null 
where
    promo_program_id=?

delete 
from
    t_promo_program 
where
    promo_program_id=? 
    and last_change=?

Я не знаю, с чего начать поиск источника проблемы.

Ответы [ 2 ]

3 голосов
/ 23 апреля 2010

Ой, это было пропущенное поле "mappedBy" в PromoProgram.

1 голос
/ 23 апреля 2010

Дважды проверьте, поддерживаете ли вы двустороннюю связь. То есть; убедитесь, что все PromoProgramParam сущности, которые ссылаются на PromoProgram в качестве его родителя, также содержатся в списке params указанного родителя. Это хорошая идея, чтобы убедиться, что это происходит независимо от того, какая сторона «инициирует» ассоциацию, если хотите; если setPromoProgram вызывается для PromoProgramParam, то установщик автоматически добавит себя в список params PromoProgram. И наоборот, при вызове addPromoProgramParam для PromoProgram установите его в качестве родителя параметра.

Я также сталкивался с этой проблемой и раньше, и это происходило из-за несоблюдения двунаправленной согласованности. Я отладил в Hibernate и обнаружил, что он не мог каскадировать операцию удаления для детей, потому что их не было в списке. Однако они наверняка присутствовали в базе данных и вызывали исключения FK, поскольку Hibernate пытался удалить только родителя, не удаляя сначала его дочерних элементов (что вы, вероятно, также встречали с @NonNull на месте).

К вашему сведению, я полагаю, что «EJB 3.0» для создания поля PromoProgramParam.promoProgram (скажем, 100 раз), не допускающего обнуления, это установить необязательный атрибут = false в аннотации @ManyToOne.

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