Re: preferred practice for handling referential integrity errors?

From: Mike Kienenberger (mkienen..laska.net)
Date: Fri Nov 26 2004 - 13:25:28 EST

  • Next message: Bryan Lewis: "Re: preferred practice for handling referential integrity errors?"

    Bryan Lewis <brya..aine.rr.com> wrote:
    > Our database has an occasional referential integrity problem, usually
    > from records written years ago. When running with our usual Oracle
    > adapter we haven't had any troubles with such errors; Cayenne creates a
    > transient object. A few days ago I copied a subset of our data to a
    > local Postgres database, so I could do work even if I couldn't connect
    > to the servers. (Getting ready for a bad winter in Maine, I guess. :-)
    > I was surprised to see CayenneRuntimeExceptions saying "Error resolving
    > fault, no matching row exists...". Why would an exception be thrown
    > with Postgres and not with Oracle? I didn't see an obvious explanation
    > in the source code.
    >
    > More importantly, how do people handle this? If I wanted to throw code
    > at it I could override DataContext.performQuery() and
    > CayenneDataObject.readProperty(), but there's probably an easier way.

    This is actually a relatively new change. I don't remember when it was
    introduced but it happened between 1.1M5 and 1.1RC1. I don't think it
    matters what adaptor you're using (I am using Oracle/Openbase).

    Take a look at this issue:

    http://objectstyle.org/jira/secure/ViewIssue.jspa?key=CAY-215

    I haven't had time to resolve this issue now that I'm a committer, but apply
    the patch and then you can use code like the following. I'd also recommend
    renaming DatabaseIntegrityException to FaultFailureException as that's what
    it'll eventually be called.

    Note that it is possible to have a PersistenceState.TRANSIENT object
    already, in which case you won't get an exception thrown, which is why I
    manually throw it in that case.

    I also only have this situation in a couple of specific well-known
    situations, so if you're looking for a general-purpose solution, you'd
    probably want to override dataObject.resolveFault() for all of your
    DataObjects to catch and ignore FaultFailureException to return back to the
    previous behavior.

    -Mike

                        try
                        {
                            if (dataObject.getPersistenceState() ==
    PersistenceState.TRANSIENT)
                                throw new
    DatabaseIntegrityException("dataObject.state=transient");
                            
                           // If the fault doesn't resolve, then the dataObject
    must have been invalidated
                            dataObject.resolveFault();

                                                    // All is Good..
                        }
                        catch (DatabaseIntegrityException
    aDatabaseIntegrityException)
                        {
                                                    // Record missing.
                        }



    This archive was generated by hypermail 2.0.0 : Fri Nov 26 2004 - 13:23:59 EST