CascadeType.Persist 未按预期工作
我有以下代码(当然是简化的):
@Entity
public class Foo {
@Generated
private Long id;
@OneToMany(mappedBy=foo)
@Cascade(CascadeType.PERSIST)
private Collection<Bar> bars;
...
}
@Entity
public class Bar {
@Generated
private Long id;
@ManyToOne
@NotNull
private Foo foo;
...
}
从我见过的许多示例来看,这应该有效:
Foo foo = new Foo();
Bar bar = new Bar();
bar.setFoo(foo);
Bar bar2 = new Bar();
bar2.setFoo(foo);
foo.bars.add(bar);
foo.bars.add(bar2);
hibernateTemplate.save(foo);
当我说“这应该有效”时,我的意思是我期望发生的事情是当我查看 数据库表 Foo 我将在 Foo 中包含一行(假设 id =1 ),在 Bar 中包含两行,每一行在 foo_id 列中具有值 1(foo 的 id)。
现实中发生的情况是我在 Bar.foo 上遇到 Exception:
org.hibernate.PropertyValueException: not-null property references a null or transient value:
。 如果我删除 @NotNull,保存会成功,但 foo_id 列中的值为 null,而不是值 1。
所以我的问题是: 这是 Hibernate 中的一个已知错误,Cascade persist 不起作用,还是我只是不了解如何使用它?
感谢您的帮助。
I have the following code (simplified of course):
@Entity
public class Foo {
@Generated
private Long id;
@OneToMany(mappedBy=foo)
@Cascade(CascadeType.PERSIST)
private Collection<Bar> bars;
...
}
@Entity
public class Bar {
@Generated
private Long id;
@ManyToOne
@NotNull
private Foo foo;
...
}
From the many examples I've seen, this should work:
Foo foo = new Foo();
Bar bar = new Bar();
bar.setFoo(foo);
Bar bar2 = new Bar();
bar2.setFoo(foo);
foo.bars.add(bar);
foo.bars.add(bar2);
hibernateTemplate.save(foo);
When I say, "this should work" I mean that what I expect to happen is when I look at
the DB table Foo I will have a row for Foo (let's assume with id =1 ) and two rows in Bar, each with the value 1 (the id of foo) in the column foo_id.
What happens in reality is I get an Exception:
org.hibernate.PropertyValueException: not-null property references a null or transient value:
on Bar.foo.
If I remove the @NotNull, the save succeeds but I have null in the foo_id column as opposed to the value 1.
So my question is:
Is this a known bug in Hibernate that Cascade persist doesn't work or am I just not understanding something about how to use it?
Thanks for the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这不是一个错误,但记录很少
CascadeType.PERSIST
可与hibernateTemplate.persist(foo)
配合使用CascadeType.SAVE_UPDATE
与hibernateTemplate.save(foo)
配合使用在这里查看 .persist(foo) 和 .persist(foo) 之间的 4 个区别.save(foo)
请注意您正在使用 Hibernate(不是 JPA)注释
It is not a bug but is poorly documented
CascadeType.PERSIST
works withhibernateTemplate.persist(foo)
CascadeType.SAVE_UPDATE
works withhibernateTemplate.save(foo)
Look here for the 4 differences between .persist(foo) and .save(foo)
Do see that you are using Hibernate (not JPA) Annotations
可以这么说,这不是一个错误,这只是事情的运作方式。 Cascade Persist 将负责通过传递持久性将内容放入数据库中,因此您不必显式地持久化 Bars。但是,维护对象的内存状态始终是您的责任。您必须将 Foo 设置在 Bar 上。 Hibernate 无法自动为您完成这部分工作。 Cascade Persist 使您不必调用 save(bar); save(bar2);,但是当会话尝试刷新对象时,对象仍然需要处于正确的内存状态。
It's not a bug, it's just how things work, so to say. Cascade Persist will take care of getting things put into the database for you via transitive persistance, so you don't have to explicitly persist the Bars. However, it is always your responsibility to maintain the in memory state of the objects. You have to set the Foo on the Bar. Hibernate cannot automagically do that part for you. Cascade Persist stops you from having to call
save(bar); save(bar2);
, but the objects still need to be in the correct in memory state when the Session tries to flush them.您可能混合使用 JPA 和 Hibernate 注释。
检查这是否是您正在使用的 CascadeType: org.hibernate.annotations.CascadeType
您可以在此找到更长的解释 链接。
You might be mixing JPA and Hibernate annotations.
Check if this is the CascadeType you are using: org.hibernate.annotations.CascadeType
You can find a longer explanation in this link.