Persisting objects

save_Or_Update_Disconnected_Object__Updates_The_Entire_Graph

Load a customer from session.

Create a copy of customer.

Clear the session.

From one of the customer's account withdraw some money, which also results in creation of a BankTransaction as well.

Save the account and flush the session.

Account is updated.

A bank transaction is inserted.

All other bank transactions in the account are updated. These updates are of no use because they are not writing any new data to the database.

do_Not_Clear_Child_Collection

Load a customer from session.

Create a copy of customer.

Clear the session.

Serialize the addresses to data transfer objects and send it to another process for editing.

The edit process sends back a list of addresses to save them, by adding a new address.

Load the customer from session.

Map the address data transfer objects to a list of addresses.

Clear all the existing addresses from the customer.

Add all the addresses.

Save and flush.

You would get a NonUniqueObjectException.

[The exception is thrown because it would result in duplicate addresses in the session.]

donot_Replace_Collection

Load a customer from session.

Create a copy of customer.

Clear the session.

Serialize the addresses to data transfer objects and send it to another process for editing.

The edit process sends back a list of addresses to save them, by adding a new address.

Load the customer from session.

Map the address data transfer objects to a list of addresses.

Replace the existing address collection in customer with the new collection.

Hibernate complains about orphan collection.

merge_When_Entire_Graph_Is_Edited

Load a customer from session.

Create a copy of customer.

Clear the session.

From one of the copied customer's account withdraw some money, which also results in creation of a BankTransaction as well.

Merge the account to the session.

Flush.

[All bank transactions are not updated. Only the new transaction is inserted.]

edit_Collections_When_Not_Updating_The_Entire_Graph

Load a customer from session.

Create a copy of customer.

Clear the session.

Read a list of addresses.

Serialize the addresses to data transfer objects and send it to another process for editing.

The edit process sends back a list of addresses to save them, by adding a new address.

Map the address data transfer objects to a list of addresses.

Edit all the customer's addresses[1].

Flush.

[Only one customer is updated and an address is inserted]

[1] Editing a persistent collection consists of deleting missing entities, adding new entities and editing existing entities.

Inverse: http://simoes.org/docs/hibernate-2.1/155.html explains the performance reasons and of using inverse=true. But it is quite painful to maintain bi-directional relationships between persisted objects.

save_Or_Update_Fails_If_Inverse_Is_False (SqlServer)

Making foreign key nullable is the only option in SqlServer.

save_Or_Update_Works_Without_Inverse_Relationship_Using_Deferred_Constraints (Oracle)

Oracle allows you to defer constraints checks to commit.

So if you have a constraint like "constraint FK_TransactionsAccount foreign key(AccountId) references Accounts(Id)", you can alter it to defer constraints by using,

"alter table Transactions modify (AccountId not null deferrable initially deferred);".