Hibernate version:3.0.5
Hi,
1. Introduction
I'm new in this forum and a new Hibernate user. I'm really impressed by its features.
I currently plan to change our own persistence layer into Hibernate.
In order to keep existing functionality I've got one open issue: urecoverable exceptions.
Of course I've read the documentation, found several similar topics and know the answers,
but I've still got a doubt and please take a look at this.
2. Example
Let's start with a simplified example. I suspect
that this is very uncommon case but it can find an application in low level processes
like database synchronizing, data loaders etc. So this, in my case, is a standalone application
that keeps a single instance of a Session. Other processes can modify the database as well.
The client code invoking runBestEffortInserts has the opportunity to "handle" the customers that caused
exceptions (for example unique constraint violations).
Code:
// This is an impelmentation of "best effort" operation. This operation
// inserts N customers into the database. Each insert should not propagate
// any exception (I've simplified the case, so it is any Exception), but returns information of its status.
Result[] runBestEffortInserts(Session session, Customer[] customers) {
Result[] results = new Result[customers.length];
Transaction tx = session.beginTransaction();
for (int i = 0; i < customers.length; i++) {
Result result = new Result();
try {
// Notice that we don't want to do any refreshes from the database here, because
// additional SELECTs would have an impact on the performance.
session.save(customer[i]);
// Execute a database INSERT immediately. Let's assume that this will be only one
// INSERT (i.e. no cascade saves, no inheritance, no previously queued DML events
// in that session).
session.flush();
result.setStatus(true); // Report success.
} catch (Exception e) {
result.setStatus(false); // Report failure.
result.setException(e);
// HERE
// But in this case, according to Hibernate we have to rollback the transaction
// and reopen the session.
// We don't want to abort the transaction here and start all over again because we would have to
// iterate once more (maybe even N - 1 iterations) that in this case is not acceptable.
}
results[i] = result;
}
tx.commit(); // It should commit to the database only successful operations (best effort).
return results;
}
...
// Operation entry result. status == true means Success, otherwise Error.
// When status is false the error attribute stores an exception.
class Result {
private boolean status;
private boolean Exception exception;
...
}
3. Summary
JDBC "allows" that algorithm. Well, depending on the underlying database engine. (There will be no
problems on Oracle but on PostgreSQL, like in Hibernate an exception during the transaction
leads it to the invalid state (but in that case savepoints could also be used).)
It seems to me that in the above case the possibility to recover from the exception would be very welcome, to
fully use the power of Hibernate engine (i.e. preparation of the INSERT, cache etc.) here. Without that
(assuming that I don't want to abort the transaction or invoke any additional selects) I will probably have to
think of some workarounds.
4. Question
Do you plan to introduce recoverable exceptions? I'm aware that I've described this issue only
from my point of view, but I will appreciate any help in that matter.