CascadeType.Persist无法按预期工作

时间:2011-07-29 06:43:32

标签: java hibernate spring annotations

我有以下代码(当然简化):

 @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);

当我说“这应该有效”时,我的意思是我期待发生的事情就是当我看到的时候 DB表Foo我将为Foo设置一个行(让我们假设id = 1)和Bar中的两行,每行在foo_id列中都有值1(foo的id)。

现实中发生的事情是我得到一个例外:

org.hibernate.PropertyValueException: not-null property references a null or transient   value:
Bar.foo上的

。 如果我删除了@NotNull,则保存成功但我在foo_id列中为null而不是值1.

所以我的问题是: 这是Hibernate中的一个已知错误,Cascade持久化不起作用,或者我只是不了解如何使用它?

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

这不是一个错误,但记录不足

CascadeType.PERSIST适用于hibernateTemplate.persist(foo) CascadeType.SAVE_UPDATEhibernateTemplate.save(foo)

一起使用

Look here了解.persist(foo)和.save(foo)之间的4个差异

确实看到您正在使用Hibernate(而不是JPA)注释

org.hibernate.annotations.Cascade
org.hibernate.annotations.CascadeType

答案 1 :(得分:2)

这不是一个错误,它只是如何运作,所以说。 Cascade Persist将通过传递持久性为您提供放入数据库的内容,因此您不必明确地保留Bars。但是,始终有责任维护对象的内存状态。你必须在栏上设置Foo。 Hibernate不能自动为你做这部分。 Cascade Persist阻止您调用save(bar); save(bar2);,但当Session尝试刷新它们时,对象仍然需要处于正确的内存状态。

答案 2 :(得分:1)

您可能正在混合使用JPA和Hibernate注释。

检查这是否是您正在使用的CascadeType:org.hibernate.annotations.CascadeType

您可以在此link找到更长的解释。