Re: intermittent exception

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Thu Nov 03 2005 - 02:14:07 EST

  • Next message: Andrus Adamchik: "Re: Expression help with one-to-many relationship"

    Bryan,

    This is strange. Now I suspect that the problem is a consequence of
    an invalid snapshot registered with DataRowStore elsewhere (possibly
    by another DataContext) prior to the "resolveFault" operation, that
    simply returns a cached snapshot. This is just a guess and there is
    no an easy way to trace it down.

    One possibility to consider though... Do you ever fetch data rows or
    use SQLTemplate and then manually convert rows to Company objects via
    DataContext.objectsFromDataRows(..)? This is where type info can get
    blurry as Cayenne can't match "raw" data row query results with the
    right ExtendedTypes.

    In the future we should probably do extra type checking and
    conversions in "objectsFromDataRows" ... but there maybe an easier
    workaround in your case if this is indeed what's causing the problem.

    Andrus

    On Nov 2, 2005, at 10:06 PM, Bryan Lewis wrote:

    > Last week I wrote about this ClassCastException (see below) and
    > Andrus recommended debugging it by overriding writePropertyDirectly
    > (). I did that in our production app (since that's the only place
    > the problem was occurring) and waited a couple of days for it to
    > happen again. The write method is:
    >
    > public void writePropertyDirectly(String propName, Object val)
    > {
    > // Log only the two Boolean properties where I've seen the
    > problem.
    > if (propName != null
    > && (propName.equals("isPremiumClient") ||
    > propName.equals("hasCustomCWUsers")))
    > {
    > // Log it if the value isn't a Boolean.
    > if (val != null && !(val instanceof java.lang.Boolean)) {
    > log.error("Company.writePropertyDirectly(" +
    > propName + ") with type " + val.getClass().getName());
    > Thread.dumpStack();
    > }
    > }
    > super.writePropertyDirectly(propName, val);
    > }
    > With some similar logging in the getter methods:
    >
    > public Boolean getIsPremiumClient()
    > {
    > Object value = readProperty("isPremiumClient");
    > if (value == null) {
    > return Boolean.FALSE;
    > }
    > if (value instanceof java.lang.Boolean) {
    > return (Boolean) value;
    > }
    > log.error("isPremiumClient property is a " + value.getClass
    > ().getName() + ", not a Boolean! " + value);
    > return Boolean.FALSE;
    > }
    > After the problem happened again, the log said:
    >
    > Company.writePropertyDirectly(isPremiumClient) with type
    > java.lang.Integer
    > java.lang.Exception: Stack trace
    > at java.lang.Thread.dumpStack(Thread.java:1064)
    > at model.Company.writePropertyDirectly(Company.java:2470)
    > at
    > org.objectstyle.cayenne.access.DataRowUtils.refreshObjectWithSnapshot(
    > DataRowUtils.java:102)
    > at org.objectstyle.cayenne.access.ObjectStore.resolveHollow
    > (ObjectStore.java:968)
    > at org.objectstyle.cayenne.CayenneDataObject.resolveFault
    > (CayenneDataObject.java:239)
    > at model.ModelObject.resolveFault(ModelObject.java:155)
    > at org.objectstyle.cayenne.CayenneDataObject.readProperty
    > (CayenneDataObject.java:249)
    > at org.objectstyle.cayenne.CayenneDataObject.readSimpleProperty
    > (CayenneDataObject.java:208)
    > at org.objectstyle.cayenne.CayenneDataObject.readNestedProperty
    > (CayenneDataObject.java:164)
    >
    > ... 60 milliseconds later in the same request...
    >
    > isPremiumClient property is a java.lang.Integer, not a Boolean! 0
    >
    >
    > It happens rarely, about once a day or two. Most of the time the
    > property written and read is a Boolean as expected. In every
    > occurrence of the write, the stack trace contains:
    > org.objectstyle.cayenne.access.DataRowUtils.refreshObjectWithSnapshot(
    > DataRowUtils.java:102)
    > There are several other Boolean attributes in our Company object
    > that are having no trouble. The two problematic ones are ones we
    > added in the last month. I'm willing to blame it on a flaky Oracle
    > 8i driver... our production server uses a slightly different driver
    > than our other servers (thin instead of OCI) and I vaguely remember
    > reading about some drivers having trouble with large objects (the
    > Company table has 53 columns). But I don't see how a flakiness
    > there could get past the ExtendedType. Assuming the type's
    > materializeObject() is always called (how could it not be?), it
    > always returns a Boolean. I'm mystified.
    >
    > We started using the thin driver four months ago so it isn't a
    > clear culprit... just guessing. We started using cayenne 1.2M4 at
    > about the same time. The problems arose only in the last few weeks.
    >
    > This isn't a crisis for us. Our code now watches for this case and
    > converts the Integer appropriately. I'm hoping this bug report
    > will shed a bit of light on something, and allow me to remove the
    > ugly hack from my code.
    >
    >
    >
    > ----- Original Message -----
    > From: Bryan Lewis
    > To: cayenne-use..bjectstyle.org
    > Sent: Friday, October 28, 2005 2:31 PM
    > Subject: intermittent exception
    >
    > We're using Cayenne 1.2M4 in production. We're seeing a rare and
    > intermittent ClassCastException when reading a Boolean property.
    > We have an ExtendedType that converts Oracle 8i integers to
    > Booleans; it's been working fine for a long time and still works
    > fine 99.9% of the time. The exception occurs on a line in the auto-
    > generated super-class such as:
    >
    > public Boolean getIsPremiumClient() {
    > return (Boolean)readProperty("isPremiumClient");
    > }
    >
    > I added some logging messages a week ago and waited for the error
    > to happen again. The readProperty() is returning an Integer rather
    > than the expected Boolean. It's as if our ExtendedType isn't being
    > invoked, once in a blue moon.
    >
    > I'm going to try upgrading or downgrading the version of Cayenne,
    > but I thought I'd ask here too since it could be a while before the
    > error happens again. I didn't see any related items in the last
    > couple of ReleaseNotes.
    >
    >
    >



    This archive was generated by hypermail 2.0.0 : Thu Nov 03 2005 - 02:14:10 EST