StringBuffer q = dbm.getSelect();
StringBuffer q = dbm.getSelect(rel);
    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;            Connection con = dbm.getConnection();            Statement stmt = con.createStatement();            DbColumn[] columns = dbm.getColumns();            Relation[] joins = dbm.getJoins();            StringBuffer q = dbm.getSelect();            if (rel.additionalTables != null) {                 q.append(',').append(rel.additionalTables);            }            try {                if (home.getSubnodeRelation() != null) {                    q.append(home.getSubnodeRelation());                } else {                    // let relation object build the query                    q.append(rel.buildQuery(home,                                            home.getNonVirtualParent(),                                            null,                                            " WHERE ",                                            true));                }                if (logSql) {                    app.logEvent("### getNodes: " + q.toString());                }                if (rel.maxSize > 0) {                    stmt.setMaxRows(rel.maxSize);                }                ResultSet rs = stmt.executeQuery(q.toString());                while (rs.next()) {                    // create new Nodes.                    Node node = createNode(rel.otherType, rs, columns, 0);                    if (node == null) {                        continue;                    }                    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);                        }                    }                    fetchJoinedNodes(rs, joins, columns.length);                }            } finally {                // tx.timer.endEvent ("getNodes "+home);                if (stmt != null) {                    try {                        stmt.close();                    } catch (Exception ignore) {                    }                }            }            return retval;        }    }