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