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]>

Reply via email to