Update: I rewrote the question to make as much sense as possible and provide the most information.
I have the following:
@Entity
public class FooLnkBar implements java.io.Serializable {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "SomeID", nullable = false)
private Foo foo;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OtherID", nullable = false)
private Bar bar;
}
@Entity
public class Foo implements java.io.Serializable {
@OneToMany(orphanRemoval=true, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "foo")
private Set<FooLnkBar> fooLnkBars = new HashSet<FooLnkBar>(0);
}
Case 1: Save everything by persisting FooLnkBar
// This correctly saves everything into the database in one shot
Foo foo = new Foo();
Bar bar = new Bar();
FooLnkBar flb = new FooLnkBar();
flb.setFoo(foo);
flb.setBar(bar);
persist(flb);
Case 2: Modify a FooLnkBar and persist a Foo
// Load a Foo from the database and get the set of FooLnkBars
Foo foo = loadFooFromDatabase();
Set<FooLnkBar> fooLnkBars = foo.getFooLnkBars();
// Delete all existing FooLnkBar objects. Alternatively use removeAll()
Iterator<FooLnkBar> it = fooLnkBars.iterator();
while (it.hasNext()) {
FooLnkBar o = it.next();
it.remove();
}
// Add some new FooLnkBars
Foo foo = new Foo();
Bar bar = new Bar();
FooLnkBar flb = new FooLnkBar();
fooLnkBars.add(flb);
foo.setFooLnkBars(fooLnkBars);
// Save all changes
persist(foo);
Case 2 does not work. Because of the cascadeType, this also removes the Foo in which the FooLnkBar resides, so the entire Foo object in Case 2 is deleted. This is bad.
Furthermore, I want to ensure that hibernate doesn't see Foo as a duplicate row when I try to persist it since FooLnkBar is a value in another table.
If I delete a Foo from the database the FooLnkBar should also be deleted from the database.
If I delete a FooLnkBar from the database the Foo should NOT be deleted from the database.
I am looking for a way to get all cases working.
Update: Changing this fixes Case 2 but breaks Case 1:
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name = "SomeID", nullable = false)
private Foo foo;
The Error message in Case 1 is now "not-null property references a null or transient value: FooLnkBar.foo"