【发布时间】:2012-06-30 09:25:53
【问题描述】:
我在 Hibernate 4 中遇到了一个在 Hibernate 3 中没有发生的问题。我正在测试一个基础 dao 类,它具有用于保存、查询等的通用方法。(不是作业)。我正在使用带有 hibernate.hbm2ddl.auto=create-drop 的嵌入式 derby 连接进行测试。
编辑:修复 cascadeType。仍然是相同的行为。即使我从 CascadeType 枚举中添加了所有可用的级联类型,它仍然会失败,除非我输入 CascadeType.ALL。不确定 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