On 4/10/07, Peter Karich <peatha..ahoo.de> wrote:
> Do you mean that "nonpersistent -> (non)persistent" will be complicated?
> Why? I can do the following:
>
> public void addToManyTarget(Object obj, ...)
> { if(this.isNonpersistent()) {
> allObjects.add(obj);
>
> } else {
> if obj.isNonpersistent() {
> nonpersistentSet.add(obj);
>
> } else {
> super.addToManyTarget(obj, ....);
> }
> }
> }
>
> Would this work?
I'm not really following what you're trying to do here. My
assumption was that your persistent and non-persistent objects were
instances of the same class. So any time you add an object as the
target of another object, you'd need to set the reverse relationship
if you want that to exist. Here's how I did it in my
cayenne-api-compatible non-persistent framework. Note that every
DataObject inherits from this BaseEntityStub superclass (instead of
CayenneDataObject). I also throw an exception if there's an attempt
to assign non-BaseEntityStub objects as relationship targets of
BaseEntityStub objects (and vise versa). I use the Cayenne template
generator to define and initialize populateRelationshipMapsFromArrays
for each Entity class, which is used to figure out the reverse
relationships for a given relationship. Again, this code duplicates
the Cayenne functionality for non-persistent objects. It does not mix
the two, but could probably be modified with what I sent you before in
order to do so.
private void checkObjectType(BaseEntity val)
{
if (null == val)
{
return;
}
if (false == val instanceof BaseEntityStub)
{
throw new RuntimeException("BaseEntity class " +
val.getClass().getName() + " is not of type BaseEntityStub");
}
}
public void setToOneTarget(String relName, BaseEntity val, boolean setReverse)
{
BaseEntity oldVal = (BaseEntity)map.get(relName);
// skip initial assignment if nothing changed
if (setReverse && safeEquals(oldVal, val))
{
return;
}
checkObjectType(val);
if (setReverse)
{
if (null != oldVal)
{
unsetReverseRelationship(relName, oldVal);
}
if (null != val)
{
setReverseRelationship(relName, val);
}
}
map.put(relName, val);
}
public void addToManyTarget(String relName, BaseEntity val,
boolean setReverse)
{
checkObjectType(val);
if (setReverse)
{
setReverseRelationship(relName, val);
}
List targetList = (List)map.get(relName);
if (null == targetList)
{
targetList = new ArrayList();
map.put(relName, targetList);
}
if (targetList.contains(val))
{
throw new RuntimeException("val " + val + " " +
val.getPrimaryKey() + " is already in " + relName);
}
targetList.add(val);
}
public void removeToManyTarget(String relName, BaseEntity val,
boolean setReverse)
{
checkObjectType(val);
if (setReverse)
{
unsetReverseRelationship(relName, val);
}
List targetList = (List)map.get(relName);
if (null == targetList)
{
throw new RuntimeException("Unsupported operation");
}
targetList.remove(val);
}
abstract protected void populateRelationshipMapsFromArrays();
private void setReverseRelationship(String relName, BaseEntity val) {
if (null == val)
{
throw new NullPointerException("val is null");
}
if (null == reverseRelationshipsForForwardRelationships)
{
populateRelationshipMapsFromArrays();
}
String reverseName =
(String)reverseRelationshipsForForwardRelationships.get(relName);
if (null != reverseName)
{
Boolean reverseToMany =
(Boolean)reverseRelationshipTypeForForwardRelationships.get(relName);
if (null != reverseToMany)
{
if (reverseToMany.booleanValue())
{
((BaseEntityStub)val).addToManyTarget(reverseName,
this, false);
}
else
{
((BaseEntityStub)val).setToOneTarget(reverseName,
this, false);
}
}
}
}
private void unsetReverseRelationship(String relName, BaseEntity val) {
if (null == val)
{
throw new NullPointerException("val is null");
}
if (null == reverseRelationshipsForForwardRelationships)
{
populateRelationshipMapsFromArrays();
}
String reverseName =
(String)reverseRelationshipsForForwardRelationships.get(relName);
if (null != reverseName)
{
Boolean reverseToMany =
(Boolean)reverseRelationshipTypeForForwardRelationships.get(relName);
if (null != reverseToMany)
{
if (reverseToMany.booleanValue())
{
((BaseEntityStub)val).removeToManyTarget(reverseName, this, false);
}
else
{
((BaseEntityStub)val).setToOneTarget(reverseName,
null, false);
}
}
}
}
> > And that's not going to handle what happens if you try to do a query
> > on object sets that are both persistent and non-persistent.
>
> I will not get the references in the nonpersistent-object-list, right?
Cayenne queries will only go against the database/persistent objects.
> Another question: How does cayenne hold objects in memory?
> As a normal reference, as WeakReference or even as PhantomReference?
I have no idea :-) I leave that kind of stuff to the experts :-)
This archive was generated by hypermail 2.0.0 : Tue Apr 10 2007 - 15:44:58 EDT