if (rel.virtual) {  node = new Node (home, kstr, safe, rel.prototype);
if (rel != null && rel.virtual) { if (rel.needsPersistence ()) node = (Node) home.createNode (kstr); else node = new Node (home, kstr, safe, rel.prototype);
    private Node getNodeByRelation (ITransaction txn, Node home, String kstr, Relation rel) throws Exception {	Node node = null;	if (rel.virtual) {	    node = new Node (home, kstr, safe, rel.prototype);		    if (rel.prototype != null) {	        node.setPrototype (rel.prototype);	        node.setDbMapping (app.getDbMapping (rel.prototype));	    } else {	        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 ();	        String[] columns = dbm.getColumns ();	        StringBuffer q = dbm.getSelect ();	        if (home.getSubnodeRelation () != null) {	            // combine our key with the constraints in the manually set subnode relation	            q.append ("WHERE ");	            q.append (rel.accessor);	            q.append (" = '");	            q.append (escape(kstr));	            q.append ("'");	            q.append (" AND ");                    q.append (home.getSubnodeRelation().trim().substring(5));	        } 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 = new Node (rel.otherType, rs, columns, safe);	        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;    }