cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robert Zeigler <robe...@puregumption.com>
Subject Re: various exceptions with cayenne 1.2RC2
Date Wed, 28 Jun 2006 16:13:20 GMT
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


Mime
View raw message