In my app I have these Hibernate-mapped types (general case):
class RoleRule {
private Role role;
private PermissionAwareEntity entity; // hibernate-mapp
I've generally used two methods of updating a collection (the many side of a one-to-many) in Hibernate. The brute force way is to clear the collection, call save on the parent, and then call flush. Then add all of the collection members back and call save on the parent again. This will delete all and then insert all. The flush in the middle is key because it forces the delete to happen before the insert. It's probably best to only use this method on small collections since it does re-insert all of them.
The second way is harder to code, but more efficient. You loop through the new set of children and manually modify the ones that are still there, delete the ones that aren't, and then add the new ones. In pseudo-code that would be:
copy the list of existing records to a list_to_delete
for each record from the form
remove it from the list_to_delete
if the record exists (based on equals()? key?)
change each field that the user can enter
else if the record doesn't exist
add it to the collection
end for
for each list_to_delete
remove it
end for
save
I've searched the Hibernate forums for many hours trying to find the right way to solve this problem. You should be able to just update your collection to make it accurate and then save the parent, but as you've found out, Hibernate tries to detach the children from the parent before deleting them and if the foreign key is not-null, it will fail.