Re: Does Cayenne handle binary primary keys (Sybase) in relationships?

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Oct 21 2003 - 16:15:08 EDT

  • Next message: Mike Kienenberger: "Re: Oracle Sequence Exception Question"

    Ok, here is a link to download patched version of Cayenne 1.0.1 that
    contains the fix mentioned below:

          
    http://objectstyle.org/downloads/cayenne/patched/cayenne-src-1.0.x-
    dev.tar.gz

    Officially this will be released as part 1.0.2 whenever we ready to
    make this release.

    Andrus

    On Tuesday, October 21, 2003, at 12:44 PM, Michael Gentry wrote:

    > Hi, I'm trying to use Cayenne against a legacy Sybase model (current
    > system uses EOF, but has "additions" to it) that uses binary primary
    > keys (a 12-byte binary data type inside Sybase).
    >
    > I put together a little test program and I could fetch a record with a
    > basic SelectQuery just fine, but when I tried to do a relationship, I
    > get exceptions. Here is what I've discovered so far ...
    >
    > My first query gives me:
    >
    > DEBUG QueryLogger: SELECT t0.identifier, t0.isAssumable, t0.isBalloon,
    > t0.numberPID FROM Pool t0, APNPoolNumber t1 WHERE t0.numberPID =
    > t1.identifier AND (t1.apnPoolNumber = ?) [bind: '461105'] - prepared
    > in 30 ms.
    > DEBUG QueryLogger: === returned 1 row. - took 150 ms.
    >
    > Pool = {[ isAssumable => false
    > isBalloon => true
    > identifier => [..9ce8c
    > number => {<oid: test.APNPoolNumber: <identifier: [..eea66>; state:
    > hollow>}
    >
    > ]<oid: test.Pool: <identifier: [..9ce8c>; state: committed>}
    >
    > Which seems fine so far. Then I try to follow the "number"
    > relationship to our "APNPoolNumber" entity and that's where it blows
    > apart with:
    >
    > java.lang.StringIndexOutOfBoundsException: String index out of range:
    > 268435450
    > at java.lang.String.charAt(String.java:460)
    > at
    > org.objectstyle.cayenne.access.QueryLogger.appendFormattedByte(QueryLog
    > ger.java:187)
    > at
    > org.objectstyle.cayenne.access.QueryLogger.sqlLiteralForObject(QueryLog
    > ger.java:157)
    > at
    > org.objectstyle.cayenne.access.QueryLogger.logQuery(QueryLogger.java:29
    > 7)
    > at
    > org.objectstyle.cayenne.access.trans.QueryAssembler.createStatement(Que
    > ryAssembler.java:135)
    > at
    > org.objectstyle.cayenne.access.DataNode.runSelect(DataNode.java:377)
    > at
    > org.objectstyle.cayenne.access.DataNode.performQueries(DataNode.java:28
    > 1)
    > at
    > org.objectstyle.cayenne.access.DataDomain.performQueries(DataDomain.jav
    > a:466)
    > at
    > org.objectstyle.cayenne.access.DataContext.performQueries(DataContext.j
    > ava:822)
    > at
    > org.objectstyle.cayenne.access.DataContext.performQuery(DataContext.jav
    > a:874)
    > at
    > org.objectstyle.cayenne.access.DataContext.performQuery(DataContext.jav
    > a:752)
    > at
    > org.objectstyle.cayenne.access.DataContext.refetchObject(DataContext.ja
    > va:626)
    > at
    > org.objectstyle.cayenne.CayenneDataObject.readProperty(CayenneDataObjec
    > t.java:198)
    > at
    > org.objectstyle.cayenne.CayenneDataObject.readNestedProperty(CayenneDat
    > aObject.java:157)
    > at Main.runTest(Main.java:39)
    > at Main.main(Main.java:71)
    > INFO QueryLogger: *** error.
    >
    >
    > I've stepped through the code and discovered what I think might be the
    > problem. In
    > org.objectstyle.cayenne.access.QueryLogger.sqlLiteralForObject(StringBu
    > ffer, Object), line 158, it appears to be building part of the SQL
    > with:
    >
    > for (int i = 0; i < len; i++) {
    > appendFormattedByte(buf, b[i]);
    > buf.append(' ');
    > }
    >
    > buf = "SELECT t0.apnPoolNumber, t0.identifier FROM APNPoolNumber t0
    > WHERE t0.identifier = ? [bind: < "
    > b = [0, 0, 0, 0, 0, 0, 0, 34, 76, -96, 110, 73]
    > len = 12
    >
    > The problem occurs when i=9 and it hits the -96 value. That's when
    > the exception occurs. It seems to me this might work if the value is
    > unsigned or if the appendFormattedByte(StringBuffer, byte) function
    > added 128 to it, such as:
    >
    > protected static void appendFormattedByte(
    > StringBuffer buf,
    > byte byteValue) {
    >
    > String hexDecode = "0123456789ABCDEF";
    >
    > if (byteValue < 0)
    > byteValue += 128;
    >
    > buf.append(hexDecode.charAt(byteValue >>> 4));
    > buf.append(hexDecode.charAt(byteValue & 0x0F));
    > }
    >
    >
    > Also, you might want to make hexDecode final so you aren't allocating
    > strings repeatedly.
    >
    > Does this seem the right thing to do? I'm *very* new to Cayenne and
    > am just looking for an ORM tool that can handle our DB model
    > (Hibernate cannot -- they explicitly do not allow for binary -- array
    > of bytes -- PKs).
    >
    > Thanks!
    >
    > /dev/mrg
    >
    >
    >



    This archive was generated by hypermail 2.0.0 : Tue Oct 21 2003 - 16:15:07 EDT