Re: various exceptions with cayenne 1.2RC2

From: Robert Zeigler (robert..uregumption.com)
Date: Wed Jun 28 2006 - 12:13:20 EDT

  • Next message: ap..indesay.co.nz: "writeNestedProperty"

    Andrus Adamchik wrote:
    >
    > On Jun 28, 2006, at 3:46 PM, Robert Zeigler wrote:
    >
    >> Interesting. I've created a bug report and attached a reproducible test
    >> case.
    >
    > Thanks!
    >
    >
    > Actually no. See Craig Russell's recent posts on a similar topic here
    > - the framework has to have a backdoor access to the persistent
    > objects and it has to be distinct from the user access. BTW JPA spec
    > provides support for explicitly defining such policy (setters vs.
    > direct field access, no matter whether the field is private or not).
    > Another example would be Java serialization mechanism.
    >

    Fair enough. But it still seems funny to me, in a way... probably
    because I don't have much knowledge in the field-based persistence
    stuff. Looks like it's time to do some reading. =) I think the thing
    that gets me is that the private variable in question isn't supposed to
    be persisted. Granted, it's being built from a persistent list, but it's
    fundamentally separate from the internal list that cayenne is, in fact,
    using to store information about the relationship. Using the same setup
    described previously (X, Y, Z, and K; also the setup for the test code),
    we have the following series of events:

    List ylistfromx = xinstance.getY();//no exception
    for(Iterator it = ylistfromx.iterator();it.hasNext();) {//no exception...
      Y yinstance = (Y) it.next();//fine... no exception...
      yinistance.getK();//fine; this wll /not/ use the private List k member
    of Y.
    }

    List ylistfromz = zinstance.getY();
    //no exception, because the private List k; field in the shared Y
    instance isn't initialized.
    for(Iterator it = ylistfromz.iterator();it.hasNext();) {
      Y yinstance = (Y) it.next();//no exception.
      yinstance.getK();//fine; won't use the private List k member of Y.
    }

    //now that the list of Y objects is initialized and faulted for both
    objects, we can safely initialize and use the private variable.
    for(Iterator it = ylistfromx.iterator();it.hasNext();) {
      Y yinstance = (Y) it.next();//fine... no exception...
      yinstance.initPrivateK();//fine.
    }
    System.out.println(zinstance.getY().size());//fine.

    The above code will execute without exception. You could go on your
    merry way, and cayenne wouldn't be confused about the non-persistent
    local variable wiith the same name as the persistent relationship. It's
    /only/ when the relationships aren't initialized, and you do something like:
    /*forces cayenne to resolve the objectList stored in the toManyList
    representing the y relationship; this involves examining the k
    relationship inside of Y...*/
    for(iterator it = xinstance.getY().iterator;it.hasNext();) {
       Y y = (Y) it.next();
       y.doSomethingThatInitializesPrivateK();
    }

    /*this is fine because it's using the already resolved list, in which
    cayenne uses a ToManyList to hold the relationship, instead of the local
    variable. We could even loop through and do getK() for all y's in
    getY(), and cayenne would be perfectly happy.*/
    xinstance.getY().size();

    /*exception thrown because in resolving the list of Y's, the y
    properties will be examined,
      and now that private List k is not null, it will be used as the
    relationship field, rather than a ToManyList. If the List is, eg, an
    ArrayList, we'll get a class cast exception...*/
    system.out.println(zinstance.getY().size());

    It's the inconsistency that gets me. =)

    Robert



    This archive was generated by hypermail 2.0.0 : Wed Jun 28 2006 - 12:13:49 EDT