Good day, all!
Sorry if this has been discussed and rejected earlier, I glanced at the
recent archives and did not find an obvious header. Pointers deeply
appreciated if I missed the obvious.
Background
I am working with a Torque-generated object model, which, for some
reason, I intend to serialize as XML (using java.beans.XMLEncoder in
Java 1.4)
The issue is that I am dealing with a fairly complex object graph, (made
even more complicated by Torque's making all relationships explicit in
both directions, so picking one end of a N to N relationship, which I
intended to only traverse one way, gives me all the objects! But I'll
struggle with that.)
A complex object graph means that many objects are referenced many
times, from various other objects.
(For example, I have a database of users, transactions made by users,
and a meaningful subset of transactions made by various users. If I pick
a set, the same user may be referenced by many transactions in the set.)
Now, as things stand, torque will re-generate the User object as many
times as it is referenced. This means bloated memory. Even worse, as the
user knows the transaction and the transaction knows the set, the
encoder will traverse all these links, every time encountering a new
object and hence the graph traversal never ends.
(I did not play with putting meaningful equals on my objects, I may have
made the situation more simple that way, but it has other negative side
effects, and I fear another quagmire....)
Proposal
So here is what I ended up doing in most of my peers:
I added a map that caches objects according to their primary keys
(assuming there is one; I am not too concerned about tables that don't,
as they often model n-n relationships anyway.) (Code below)
Note that this has many issues as well;
it makes objects more persistent than may be safe in a transactional
situation; (Though nothing ever stopped a high-level application of
holding on to its objects for inordinate amounts of time); it risks
memory bloat, etc.
To alleviate this (esp. the latter), I am going to build a map that uses
WeakReferences to keep the object. (The java.util.WeakHashMap uses weak
refs in the key... Not useful to me!)
Questions and integration
Now, I am certain that other peer methods should be protected with
normalization. I will definitely look into this, but any hint would be
appreciated.
The next step for me would be to embed this idea into the torque
BasePeer templates... so as to not pollute the non-base peers
needlessly. Now, I have a nightmare of synchronizing with the torque
group. And, true to open source form, I expect other people have taken
this on already... Is it possible to join forces? (Has it all been done
in a patch I might apply ;-)
Is there an interest in such a mechanism from the torque community, or
is it felt that the costs outweigh the gains?
Thank you for your attention,
Marc-Antoine Parent
Sample Code
public class UserPeer
extends .....om.BaseUserPeer
{
private static Map usersByPk = new TreeMap();
public static User Normalize(User sp) {
return Normalize(sp.getPrimaryKey(), sp);
}
public static User Normalize(ObjectKey pk, User sp) {
User other = (User)usersByPk.get(pk);
if (other == null) {
usersByPk.put(pk, sp);
} else if (other != sp) {
return other;
}
return sp;
}
public static User retrieveByPK(ObjectKey pk, Connection con)
throws TorqueException {
User sp = (User)usersByPk.get(pk);
if (sp == null) {
sp = BaseUserPeer.retrieveByPK(pk,
con);
sp = Normalize(pk, sp);
}
return sp;
}
public static User retrieveByPK(ObjectKey pk)
throws TorqueException {
User sp = (User)usersByPk.get(pk);
if (sp == null) {
sp = BaseUserPeer.retrieveByPK(pk);
sp = Normalize(pk, sp);
}
return sp;
}
public static void doInsert(User obj) throws TorqueException {
BaseUserPeer.doInsert(obj);
Normalize(obj);
}
public static List doSelect(Criteria criteria) throws TorqueException
{
List l = BaseUserPeer.doSelect(criteria);
ListIterator li = l.listIterator();
while (li.hasNext()) {
User sp = (User)li.next();
li.set(Normalize(sp));
}
return l;
}
public static List doSelect(Criteria criteria, Connection con)
throws TorqueException
{
List l = BaseUserPeer.doSelect(criteria, con);
ListIterator li = l.listIterator();
while (li.hasNext()) {
User sp = (User)li.next();
li.set(Normalize(sp));
}
return l;
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>