1

I'm writing an application in Java, with Hibernate, and I'm trying to do the following:

  1. Query a list of objects from the database, then for each object:
  2. Remove it from the database.
  3. Perform an operation on it.
  4. If the operation fails, modify the object and insert it back into the database.

However, I'm working with an unreliable database connection, and it is essential that the object is successfully removed from the database (step 2) before an operation is performed on it (step 3). It's important but not critical that the object is successfully re-inserted (step 4) on failure.

(The higher level requirement is that if the operation is successfully performed on the object, it CANNOT remain in the database -- that's why I concluded that I have to remove it first and ensure that it is actually removed before attempting the operation.)

I don't fully understand Hibernate sessions, transactions, and object states (e.g. "detached"). How can I accomplish this?

I have tried too many permutations of opening/closing sessions, committing/rolling back transactions, evicting/merging/persisting/saving/deleting/updating objects to list here, but everything I try fails with one error or another. I've been referring to the Hibernate docs, but basically I'm swinging in the dark here because I don't really understand what I'm doing, so any suggestions are welcome.

Jason C
  • 38,729
  • 14
  • 126
  • 182

1 Answers1

2

A transaction, basically, ensures that all the operations performed between the beginning and the end of the transaction are either sucessfully performed, or cancelled. So the state of the database either stays as it was before the beginning of a transaction (in case of a rollback), or contains all the modifications (insertions, updates, removals) done during the transaction (in case of a successful commit).

So just open a transaction, do all the operations you want, and commit the transaction. In case of any exception, rollback the transaction. The state of the database will stay unmodified, or will contain all the removals and reinsertions you made during the transaction.

Given that you don't really care about the reinsertions, you could also have a first transaction to remove everything and, if this transaction has successfully committed, one or several subsequent transactions for the operations and reinsertions.

The typical way of starting, committing and rollbacking transactions, in a non-managed environment (which I assume you're in), is described in the documentation.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks! When I commit a transaction, will it actually happen, or do I have to flush or close the session first? I.e. does the session cache transactions and wait until it's closed before it actually submits everything to the database, or am I guaranteed that if I commit a transaction, everything up to that point has been sent successfully to the database server? – Jason C Jul 15 '13 at 04:15
  • 1
    A commit is a commit, in the database meaning of a commit. It's actually committed to the database. By default, committing a transaction also flushes all the pending writes before the actual commit. So yes, if you successfuly commit, everything up to that point has been sent to the database server and committed by the database. – JB Nizet Jul 15 '13 at 06:51
  • Great! Using what you wrote, and sitting back and starting over with a clear head, I have everything working exactly the way I want it and the code is very straightforward. Thanks again! – Jason C Jul 15 '13 at 11:35