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(QueryLogger.java:187)
at
org.objectstyle.cayenne.access.QueryLogger.sqlLiteralForObject(QueryLogger.java:157)
at
org.objectstyle.cayenne.access.QueryLogger.logQuery(QueryLogger.java:297)
at
org.objectstyle.cayenne.access.trans.QueryAssembler.createStatement(QueryAssembler.java:135)
at org.objectstyle.cayenne.access.DataNode.runSelect(DataNode.java:377)
at
org.objectstyle.cayenne.access.DataNode.performQueries(DataNode.java:281)
at
org.objectstyle.cayenne.access.DataDomain.performQueries(DataDomain.java:466)
at
org.objectstyle.cayenne.access.DataContext.performQueries(DataContext.java:822)
at
org.objectstyle.cayenne.access.DataContext.performQuery(DataContext.java:874)
at
org.objectstyle.cayenne.access.DataContext.performQuery(DataContext.java:752)
at
org.objectstyle.cayenne.access.DataContext.refetchObject(DataContext.java:626)
at
org.objectstyle.cayenne.CayenneDataObject.readProperty(CayenneDataObject.java:198)
at
org.objectstyle.cayenne.CayenneDataObject.readNestedProperty(CayenneDataObject.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(StringBuffer,
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 - 12:44:06 EDT