У меня возникла проблема с Hibernate 4, которая не произошла в Hibernate 3. Я тестирую базовый класс dao, который имеет общие методы для сохранения, запросов и т. Д. . (не это не домашнее задание). Я использую встроенное дерби соединение с hibernate.hbm2ddl.auto = create-drop для целей тестирования.Каскадное сохранение не работает с Hibernate 4 и @OneToMany
EDIT: Фиксация каскадаТип. Все-таки такое же поведение. Даже если я добавлю все доступные типы каскадов из перечисления CascadeType, он все равно терпит неудачу, если я не поставлю CascadeType.ALL. Не уверен, что ВСЕ есть, что вы не можете специально перечислить.
В моих тестах я следующие отображенные классы:
@Entity
@Table(name="FOO_CHILD")
public class FooChild {
@Id
@Column(name="FOO_ID")
private Long id;
@Column(name="NAME")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
@Table(name="FOO_PARENT")
public class FooParent {
@Id
@Column(name="FOO_PARENT_ID")
private Long id;
@Column(name="NAME")
private String name;
@Fetch(FetchMode.SELECT)
@Type(type="long")
@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name="FOO_PARENT_FOO",
joinColumns={@JoinColumn(referencedColumnName="FOO_PARENT_ID")},
inverseJoinColumns={@JoinColumn(referencedColumnName="FOO_ID")})
private List<Foo> fooChild;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Foo> getFooChild() {
return fooChild;
}
public void setFooChild(List<Foo> fooChild) {
this.fooChild = fooChild;
}
}
И тогда я пытаюсь сохранить:
FooChild fooChild = new FooChild();
fooChild.setId(1L);
fooChild.setName("fooChild");
FooParent fooParent = new FooParent();
fooParent.setId(1L);
fooParent.setName("fooParent");
fooParent.setFooChild(new ArrayList<FooChild>(Arrays.asList(fooChild)));
session.save(fooParent);
session.flush();
session.clear();
я получаю следующий след:
org.hibernate.exception.ConstraintViolationException: INSERT on table 'FOO_PARENT_FOO' caused a violation of foreign key constraint 'FKF18290CAECA19CB8' for key (1). The statement has been rolled back.
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
...
Я заметил выполняется следующее sql:
Hibernate:
insert
into
foo_parent
(name, foo_parent_id)
values
(?, ?, ?, ?)
Hibernate:
insert
into
foo_parent_foo
(foo_parent, foo_child)
values
(?, ?)
Кажется, он пытается вставить в коллекцию до каскадирования сохранения до объекта FooChild.
Если я изменить FooParent, чтобы это:
@OneToMany(cascade={CascadeType.ALL})
Проблема уходит.
Как я уже сказал, это работает с hibernate 3, поэтому я не уверен, почему он ведет себя по-другому.
'cascade = {CascadeType.MERGE, CascadeType.MERGE}': здесь нет каскада для SAVE_UPDATE. –
Извините, я попробовал несколько вещей и имею ошибку в том, к чему я вернулся. Он должен читать CascadeType.PERSIST, CascadeType.MERGE – Matt