-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Recoverable exceptions
PostPosted: Tue Aug 23, 2005 9:44 am 
Newbie

Joined: Tue Aug 23, 2005 3:48 am
Posts: 4
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.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 9:55 am 
Senior
Senior

Joined: Thu May 12, 2005 11:40 pm
Posts: 125
Location: Canada
When the docs state that exceptions are unrecoverable, they mean that the session cache may be out of sync with the underlying datasource after an exception occurs. As long as you keep that in mind and evict() any possibly stale instances before querying for them, you can write correct exception recovery code.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 12:21 pm 
Newbie

Joined: Tue Aug 23, 2005 3:48 am
Posts: 4
Thanks for reply. OK, this is true in the case of my example where there is one database insert per save()/flush() and this will work fine.

So let's now try a more complicated example. Assume that there is vertical inheritance (on 2 tables), so one invocation of save()/flush() will invoke two database inserts. In that case not only the cache is out of sync but also ActionQueue in SessionImpl (I've followed your hint and looked to the Hibernate code) since there is no "modification log" telling which action (database insert here) has been successful and which not. This is of course OK according to the docs.

Now I see that this isn't an easy task to handle this case the way I would like... Hopefully your solution will be sufficient for me. Thanks again.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 6:04 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Nebob wrote:
When the docs state that exceptions are unrecoverable, they mean that the session cache may be out of sync with the underlying datasource after an exception occurs.

No, exceptions should be considered as uncoverable. Exceptions raised when the session is in fragile state create some inconsistency in the session internal system itself, making it potentially unusable.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 4:42 am 
Newbie

Joined: Tue Aug 23, 2005 3:48 am
Posts: 4
I've also found in the article "Versant Spam"http://blog.hibernate.org/cgi-bin/blosxom.cgi/index.html?find=exception+recoverable&plugin=find&path=:
Quote:
I'm currently discussing with Mike Keith (Oracle) and Patrick Linskey (Solarmetric) to understand if there are any good cases for allowing recoverable exceptions in the EJB 3.0 spec, and if we find some (Patrick seems to believe there are some), we will of course implement that in Hibernate.


So, this is the reason of my question...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 5:32 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Patrick did not convince us so far :-)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 10:05 am 
Newbie

Joined: Tue Aug 23, 2005 3:48 am
Posts: 4
:-) By the way, I see that in the upcoming version of PostgreSQL (8.1) there will be an interesting feature (connected somehow to our topic):

Quote:
-Add an option to automatically use savepoints for each statement in a multi-statement transaction.

When enabled, this would allow errors in multi-statement transactions to be automatically ignored.


(http://www.postgresql.org/docs/faqs.TODO.html)

I assume here, that "ignored" means "not aborting the transaction but raised", but I may be wrong.

So, we can implement a "business logic" that uses the feature of recovering from database exceptions (like unique constraint violation) in, say, PL/PgSQL (in future), JDBC (depending on the RDBMS), Oracle PLSQL but not (easily) in Hibernate.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.