if (logSql) { app.logEvent("### getNodeByRelation: " + q.toString()); }
    private Node getNodeByRelation(ITransaction txn, Node home, String kstr, Relation rel)                            throws Exception {        Node node = null;        if ((rel != null) && rel.virtual) {            if (rel.needsPersistence()) {                node = (Node) home.createNode(kstr);            } else {                node = new Node(home, kstr, safe, rel.prototype);            }            // set prototype and dbmapping on the newly created virtual/collection node            node.setPrototype(rel.prototype);            node.setDbMapping(rel.getVirtualMapping());        } else if ((rel != null) && (rel.groupby != null)) {            node = home.getGroupbySubnode(kstr, false);            if ((node == null) &&                    ((rel.otherType == null) || !rel.otherType.isRelational())) {                node = (Node) db.getNode(txn, kstr);                node.nmgr = safe;            }            return node;        } else if ((rel == null) || (rel.otherType == null) ||                       !rel.otherType.isRelational()) {            node = (Node) db.getNode(txn, kstr);            node.nmgr = safe;            node.setDbMapping(rel.otherType);            return node;        } else {            Statement stmt = null;            try {                DbMapping dbm = rel.otherType;                Connection con = dbm.getConnection();                DbColumn[] columns = dbm.getColumns();                Relation[] joins = dbm.getJoins();                StringBuffer q = dbm.getSelect(rel);                if (home.getSubnodeRelation() != null && !rel.isComplexReference()) {                    // combine our key with the constraints in the manually set subnode relation                    q.append(" WHERE ");                    q.append(dbm.getTableName());                    q.append(".");                    q.append(rel.accessName);                    q.append(" = '");                    q.append(escape(kstr));                    q.append("'");                    // add join contraints in case this is an old oracle style join                    dbm.addJoinConstraints(q, " AND ");                    // add potential constraints from manually set subnodeRelation                    String subrel = home.getSubnodeRelation().trim();                    if (subrel.length() > 5) {                        q.append(" AND (");                        q.append(subrel.substring(5).trim());                        q.append(")");                    }                } else {                    q.append(rel.buildQuery(home,                                            home.getNonVirtualParent(),                                            kstr,                                            " WHERE ",                                            false));                }                if (logSql) {                    app.logEvent("### getNodeByRelation: " + q.toString());                }                stmt = con.createStatement();                ResultSet rs = stmt.executeQuery(q.toString());                if (!rs.next()) {                    return null;                }                node = createNode(rel.otherType, rs, columns, 0);                fetchJoinedNodes(rs, joins, columns.length);                if (rs.next()) {                    throw new RuntimeException("More than one value returned by query.");                }                // Check if node is already cached with primary Key.                if (!rel.usesPrimaryKey()) {                    Key pk = node.getKey();                    Node existing = (Node) cache.get(pk);                    if ((existing != null) && (existing.getState() != Node.INVALID)) {                        node = existing;                    }                }            } finally {                if (stmt != null) {                    try {                        stmt.close();                    } catch (Exception ignore) {                    }                }            }        }        return node;    }