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

From: Andriy Shapochka (ashapochk..otmail.com)
Date: Thu Oct 23 2003 - 03:36:40 EDT

  • Next message: Andrus Adamchik: "Re: runtime error - can't find generated class"

    ----- Original Message -----
    From: "Andrus Adamchik" <andru..bjectstyle.org>
    To: <cayenne-use..bjectstyle.org>
    Sent: Wednesday, October 22, 2003 11:09 PM
    Subject: Re: Does Cayenne handle binary primary keys (Sybase) in
    relationships?

    > Hi Michael,
    >
    > I think I might know what is causing the latest problem. ObjectId is
    > used as a key to identify objects in the ObjectStore. So as a map key
    > it must have a properly implemented hashCode() method. With String or
    > numeric PKs hashCode() works since it relies on AbstractMap.hashCode()
    > implementation. With byte[] it does not, since default hashCode for
    > arrays of primitives seems to be based on identity rather than element
    > equality. In fact I just wrote a test case that confirms my suspicion.
    >
    > I will do some more testing, and see how to create a smarter hashCode
    > implementation. I'll keep you posted.
    >

    Exactly so, and for arrays of Objects it is true as well.
    Don't know whether it helps but for arrays the following hashing and
    equality algorithms may be used (taken from the Trove docs, see my earlier
    posting):

            public int computeHashCode(Object o) {
                char[] c = (char[])o;
                // use the shift-add-xor class of string hashing functions
                // cf. Ramakrishna and Zobel, "Performance in Practice of String
    Hashing Functions"
                int h = 31; // seed chosen at random
                for (int i = 0; i < c.length; i++) { // could skip invariants
                    h = h ^ ((h << 5) + (h >> 2) + c[i]); // L=5, R=2 works well
    for ASCII input
                }
                return h;
            }

            public boolean equals(Object o1, Object o2) {
                char[] c1 = (char[])o1;
                char[] c2 = (char[])o2;
                if (c1.length != c2.length) { // could drop this check for
    fixed-length keys
                    return false;
                }
                for (int i = 0, len = c1.length; i < len; i++) { // could skip
    invariants
                    if (c1[i] != c2[i]) {
                        return false;
                    }
                }
                return true;
           }

    Pretty sure, byte[] can use the same numbers for hashing. Whether the
    distribution of hash key values generated by this algorithm better than that
    in Apache Commons' HashCodeBuilder or not is difficult to say, it should
    work faster
    though.

    Andriy.



    This archive was generated by hypermail 2.0.0 : Thu Oct 23 2003 - 03:31:01 EDT