CascadeType.Persist does not work as expected
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:
开发者_JS百科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.
It is not a bug but is poorly documented
CascadeType.PERSIST
works with hibernateTemplate.persist(foo)
CascadeType.SAVE_UPDATE
works with hibernateTemplate.save(foo)
Look here for the 4 differences between .persist(foo) and .save(foo)
Do see that you are using Hibernate (not JPA) Annotations
org.hibernate.annotations.Cascade
org.hibernate.annotations.CascadeType
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.
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.
精彩评论