I have a pretty standard @OneToMany mapping in JPA with no cascades (the default setting), like this:
@JoinColumn(name = "PARENT_ID")
@OneToMany(fetch = FetchType.LAZY)
@OrderBy("date")
private List<ItemRow> items;
My problem is, when I try to em.merge() this entity, Hibernate thinks that if an item is not present in the collection it's supposed to be removed from the database. Given that I don't call em.remove() explicitly, the resulting SQL doesn't really try to delete the items, Hibernate just tries to do SET PARENT_ID = NULL
which fails due to database constraints, thankfully.
I don't want to load all items just to save their parent to the database. That would be silly. My user interface is paginated and when a client sends a partial collection, that doesn't mean that other items should be deleted, I just want to insert and update the rows that the user sees and leave the unlisted ones alone.
What should I do? Should I remove the collection mapping from the parent entity? Is there a setting for “no cascading, really, use this only for loading”?
I'm using JBoss EAP 6.4, which contains Hibernate 4.2.18.
After reading the comments I decided to save the parent entity with plain JDBC so I can control exactly what happens. The resulting code is kind of tedious but it's robust enough once written carefully.
After inserting or updating the parent entity I can loop thru all children and save them using JPA one by one. That part works fine.
I wish this could be more automated, but having an in-memory collection that doesn't correspond exactly to what is going to be saved seems to be a kind of unsupported operation.