Transactor tx = (Transactor) Thread.currentThread ();
    public List getNodes (Node home, Relation rel) throws Exception {	// This does not apply for groupby nodes - use getNodeIDs instead	if (rel.groupby != null)	    return getNodeIDs (home, rel);	Transactor tx = (Transactor) Thread.currentThread ();	// tx.timer.beginEvent ("getNodes "+home);	if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) {	    // this should never be called for embedded nodes	    throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home);	} else {	    List retval = new ArrayList ();	    DbMapping dbm = rel.otherType;	    TableDataSet tds =  new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());	    try {	        if (home.getSubnodeRelation() != null) {	            // HACK: cut off the "where" part of manually set subnoderelation	            tds.where (home.getSubnodeRelation().trim().substring(5));	        } else {	            // let relation object build the query	            tds.where (rel.buildQuery (home, home.getNonVirtualParent (), null, "", false));	            if (rel.getOrder () != null)	                tds.order (rel.getOrder ());	        }		        if (logSql)	           app.logEvent ("### getNodes: "+tds.getSelectString());	        if (rel.maxSize > 0)	            tds.fetchRecords (rel.maxSize);	        else	            tds.fetchRecords ();		        for (int i=0; i<tds.size (); i++) {	            // create new Nodes.	            Record rec = tds.getRecord (i);	            Node node = new Node (rel.otherType, rec, safe);	            Key primKey = node.getKey ();	            retval.add (new NodeHandle (primKey));	            // do we need to synchronize on primKey here?	            synchronized (cache) {	                Node oldnode = (Node) cache.put (primKey, node);	                if (oldnode != null && oldnode.getState() != INode.INVALID) {	                    cache.put (primKey, oldnode);	                }	            }	        }	    } finally {	        // tx.timer.endEvent ("getNodes "+home);	        if (tds != null)  try {	            tds.close ();	        } catch (Exception ignore) {}	    }	    return retval;	}    }