Use JDBC API directly for all queries. The only place where Village is still used is for inserts and updates.

This commit is contained in:
hns 2002-11-06 10:49:41 +00:00
parent 4529071cf4
commit dfc2431343
4 changed files with 207 additions and 132 deletions

View file

@ -52,6 +52,10 @@ public final class DbMapping implements Updatable {
HashMap prop2db; HashMap prop2db;
// Map of db columns to Relations objects // Map of db columns to Relations objects
HashMap db2prop; HashMap db2prop;
// prerendered list of columns to fetch from db
String columns = null;
// pre-rendered select statement
String select = null;
// db field used as primary key // db field used as primary key
private String idField; private String idField;
@ -135,7 +139,9 @@ public final class DbMapping implements Updatable {
* for rewire to work, all other db mappings must have been initialized and registered. * for rewire to work, all other db mappings must have been initialized and registered.
*/ */
public synchronized void update () { public synchronized void update () {
// reset columns
columns = select = null;
// read in properties
table = props.getProperty ("_table"); table = props.getProperty ("_table");
idgen = props.getProperty ("_idgen"); idgen = props.getProperty ("_idgen");
// see if there is a field which specifies the prototype of objects, if different prototypes // see if there is a field which specifies the prototype of objects, if different prototypes
@ -564,19 +570,71 @@ public final class DbMapping implements Updatable {
return schema; return schema;
} }
/**
* Return a Village Schema object for this DbMapping.
*/
public synchronized String getColumns() throws ClassNotFoundException, SQLException {
if (!isRelational ())
throw new SQLException ("Can't get Schema for non-relational data mapping");
if (source == null && parentMapping != null)
return parentMapping.getColumns ();
// Use local variable s to avoid synchronization (schema may be nulled elsewhere)
if (columns == null) {
// we do two things here: set the SQL type on the Relation mappings
// and build a string of column names.
Connection con = getConnection ();
Statement stmt = con.createStatement ();
ResultSet rs = stmt.executeQuery ("select * from "+getTableName()+" where 1 = 0");
if (rs == null)
throw new SQLException ("Error retrieving DB scheme for "+this);
ResultSetMetaData meta = rs.getMetaData ();
// ok, we have the meta data, now loop through mapping...
// StringBuffer cbuffer = new StringBuffer (getIDField ());
for (Iterator i=getDBPropertyIterator(); i.hasNext(); ) {
Relation rel = (Relation) i.next ();
if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE)
continue;
// cbuffer.append (",");
// cbuffer.append (rel.getDbField());
int idx = rs.findColumn (rel.getDbField());
rel.setColumnType (meta.getColumnType (idx));
}
// columns = cbuffer.toString();
columns = " * ";
}
return columns;
}
public StringBuffer getSelect () throws SQLException, ClassNotFoundException {
String sel = select;
if (sel != null)
return new StringBuffer (sel);
StringBuffer s = new StringBuffer ("select ");
s.append (getColumns ());
s.append (" from ");
s.append (table);
s.append (" ");
// cache rendered string for later calls.
select = s.toString();
return s;
}
/** /**
* Return true if values for the column identified by the parameter need * Return true if values for the column identified by the parameter need
* to be quoted in SQL queries. * to be quoted in SQL queries.
*/ */
public boolean needsQuotes (String columnName) throws SQLException { public boolean needsQuotes (String columnName) throws SQLException {
if (table == null && parentMapping != null)
return parentMapping.needsQuotes (columnName);
try { try {
Schema s = getSchema (); Relation rel = (Relation) db2prop.get (columnName);
if (s == null) if (rel == null)
throw new SQLException ("Error retrieving relational schema for "+this); throw new SQLException ("Error retrieving relational schema for "+this);
Column c = s.getColumn (columnName); // make sure columns are initialized and up to date
if (c == null) if (columns == null)
throw new SQLException ("Column "+columnName+" not found in "+this); getColumns();
switch (c.typeEnum()) { switch (rel.getColumnType()) {
case Types.CHAR: case Types.CHAR:
case Types.VARCHAR: case Types.VARCHAR:
case Types.LONGVARCHAR: case Types.LONGVARCHAR:

View file

@ -12,11 +12,11 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.io.*; import java.io.*;
import java.sql.Types; import java.sql.*;
import helma.objectmodel.*; import helma.objectmodel.*;
import helma.util.*; import helma.util.*;
import helma.framework.IPathElement; import helma.framework.IPathElement;
import com.workingdogs.village.*; // import com.workingdogs.village.*;
/** /**
@ -234,16 +234,15 @@ public final class Node implements INode, Serializable {
/** /**
* Constructor used for nodes being stored in a relational database table. * Constructor used for nodes being stored in a relational database table.
*/ */
public Node (DbMapping dbm, Record rec, WrappedNodeManager nmgr) throws DataSetException { public Node (DbMapping dbm, ResultSet rs, WrappedNodeManager nmgr) throws SQLException {
this.nmgr = nmgr; this.nmgr = nmgr;
// see what prototype/DbMapping this object should use // see what prototype/DbMapping this object should use
dbmap = dbm; dbmap = dbm;
String protoField= dbmap.getPrototypeField (); String protoField= dbmap.getPrototypeField ();
if (protoField != null) { if (protoField != null) {
Value val = rec.getValue (protoField); String protoName = rs.getString (protoField);
if (val != null && !val.isNull ()) { if (protoName != null) {
String protoName = val.asString ();
dbmap = nmgr.getDbMapping (protoName); dbmap = nmgr.getDbMapping (protoName);
if (dbmap == null) { if (dbmap == null) {
// invalid prototype name! // invalid prototype name!
@ -254,10 +253,10 @@ public final class Node implements INode, Serializable {
} }
setPrototype (dbmap.getTypeName ()); setPrototype (dbmap.getTypeName ());
id = rec.getValue (dbmap.getIDField ()).asString (); id = rs.getString (dbmap.getIDField ());
// checkWriteLock (); // checkWriteLock ();
String nameField = dbmap.getNameField (); String nameField = dbmap.getNameField ();
name = nameField == null ? id : rec.getValue (nameField).asString (); name = nameField == null ? id : rs.getString (nameField);
if (name == null || name.length() == 0) if (name == null || name.length() == 0)
name = dbmap.getTypeName() + " " + id; name = dbmap.getTypeName() + " " + id;
// set parent for user objects to internal userroot node // set parent for user objects to internal userroot node
@ -276,60 +275,61 @@ public final class Node implements INode, Serializable {
if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE) if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE)
continue; continue;
Value val = rec.getValue (rel.getDbField ()); // Value val = rec.getValue (rel.getDbField ());
// if (val.isNull ()) // if (val.isNull ())
// continue; // continue;
Property newprop = new Property (rel.propName, this); Property newprop = new Property (rel.propName, this);
if (val.isNull ()) // if (val.isNull ())
newprop.setStringValue (null); // newprop.setStringValue (null);
else switch (val.type ()) { // else
switch (rel.getColumnType()) {
case Types.BIT: case Types.BIT:
newprop.setBooleanValue (val.asBoolean()); newprop.setBooleanValue (rs.getBoolean(rel.getDbField()));
break; break;
case Types.TINYINT: case Types.TINYINT:
case Types.BIGINT: case Types.BIGINT:
case Types.SMALLINT: case Types.SMALLINT:
case Types.INTEGER: case Types.INTEGER:
newprop.setIntegerValue (val.asLong()); newprop.setIntegerValue (rs.getLong(rel.getDbField()));
break; break;
case Types.REAL: case Types.REAL:
case Types.FLOAT: case Types.FLOAT:
case Types.DOUBLE: case Types.DOUBLE:
newprop.setFloatValue (val.asDouble()); newprop.setFloatValue (rs.getDouble(rel.getDbField()));
break; break;
case Types.DECIMAL: case Types.DECIMAL:
case Types.NUMERIC: case Types.NUMERIC:
java.math.BigDecimal num = val.asBigDecimal (); java.math.BigDecimal num = rs.getBigDecimal (rel.getDbField());
if (num.scale() > 0) if (num.scale() > 0)
newprop.setFloatValue (val.asDouble()); newprop.setFloatValue (rs.getDouble(rel.getDbField()));
else else
newprop.setIntegerValue (val.asLong()); newprop.setIntegerValue (rs.getLong(rel.getDbField()));
break; break;
case Types.LONGVARBINARY: case Types.LONGVARBINARY:
case Types.VARBINARY: case Types.VARBINARY:
case Types.BINARY: case Types.BINARY:
newprop.setStringValue (val.asString()); newprop.setStringValue (rs.getString(rel.getDbField()));
break; break;
case Types.LONGVARCHAR: case Types.LONGVARCHAR:
case Types.CHAR: case Types.CHAR:
case Types.VARCHAR: case Types.VARCHAR:
case Types.OTHER: case Types.OTHER:
newprop.setStringValue (val.asString()); newprop.setStringValue (rs.getString(rel.getDbField()));
break; break;
case Types.DATE: case Types.DATE:
case Types.TIME: case Types.TIME:
case Types.TIMESTAMP: case Types.TIMESTAMP:
newprop.setDateValue (val.asTimestamp()); newprop.setDateValue (rs.getTimestamp(rel.getDbField()));
break; break;
case Types.NULL: case Types.NULL:
@ -338,10 +338,13 @@ public final class Node implements INode, Serializable {
// continue; // continue;
default: default:
newprop.setStringValue (val.asString()); newprop.setStringValue (rs.getString(rel.getDbField()));
break; break;
} }
if (rs.wasNull())
newprop.setStringValue (null);
if(propMap == null) if(propMap == null)
propMap = new Hashtable (); propMap = new Hashtable ();
propMap.put (rel.propName.toLowerCase(), newprop); propMap.put (rel.propName.toLowerCase(), newprop);

View file

@ -601,26 +601,26 @@ public final class NodeManager {
// Transactor tx = (Transactor) Thread.currentThread (); // Transactor tx = (Transactor) Thread.currentThread ();
// tx.timer.beginEvent ("generateID "+map); // tx.timer.beginEvent ("generateID "+map);
QueryDataSet qds = null;
String retval = null; String retval = null;
Statement stmt = null;
try { try {
Connection con = map.getConnection (); Connection con = map.getConnection ();
String q = "SELECT MAX("+map.getIDField()+") FROM "+map.getTableName(); String q = "SELECT MAX("+map.getIDField()+") FROM "+map.getTableName();
qds = new QueryDataSet (con, q); stmt = con.createStatement ();
qds.fetchRecords (); ResultSet rs = stmt.executeQuery (q);
// check for empty table // check for empty table
if (qds.size () == 0) { if (!rs.next()) {
long currMax = map.getNewID (0); long currMax = map.getNewID (0);
retval = Long.toString (currMax); retval = Long.toString (currMax);
} else { } else {
long currMax = qds.getRecord (0).getValue (1).asLong (); long currMax = rs.getLong (1);
currMax = map.getNewID (currMax); currMax = map.getNewID (currMax);
retval = Long.toString (currMax); retval = Long.toString (currMax);
} }
} finally { } finally {
// tx.timer.endEvent ("generateID "+map); // tx.timer.endEvent ("generateID "+map);
if (qds != null) try { if (stmt != null) try {
qds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
return retval; return retval;
@ -635,18 +635,18 @@ public final class NodeManager {
// Transactor tx = (Transactor) Thread.currentThread (); // Transactor tx = (Transactor) Thread.currentThread ();
// tx.timer.beginEvent ("generateID "+map); // tx.timer.beginEvent ("generateID "+map);
QueryDataSet qds = null; Statement stmt = null;
String retval = null; String retval = null;
try { try {
Connection con = map.getConnection (); Connection con = map.getConnection ();
String q = "SELECT "+map.getIDgen()+".nextval FROM dual"; String q = "SELECT "+map.getIDgen()+".nextval FROM dual";
qds = new QueryDataSet (con, q); stmt = con.createStatement();
qds.fetchRecords (); ResultSet rs = stmt.executeQuery (q);
retval = qds.getRecord (0).getValue (1).asString (); retval = rs.getString (1);
} finally { } finally {
// tx.timer.endEvent ("generateID "+map); // tx.timer.endEvent ("generateID "+map);
if (qds != null) try { if (stmt != null) try {
qds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
return retval; return retval;
@ -746,31 +746,31 @@ public final class NodeManager {
List retval = new ArrayList (); List retval = new ArrayList ();
DbMapping dbm = rel.otherType; DbMapping dbm = rel.otherType;
TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ()); Connection con = dbm.getConnection ();
Statement stmt = con.createStatement ();
StringBuffer q = dbm.getSelect ();
try { try {
if (home.getSubnodeRelation() != null) { if (home.getSubnodeRelation() != null) {
// HACK: cut off the "where" part of manually set subnoderelation q.append (home.getSubnodeRelation());
tds.where (home.getSubnodeRelation().trim().substring(5));
} else { } else {
// let relation object build the query // let relation object build the query
tds.where (rel.buildQuery (home, home.getNonVirtualParent (), null, "", false)); q.append (" where ");
q.append (rel.buildQuery (home, home.getNonVirtualParent (), null, "", false));
if (rel.getOrder () != null) if (rel.getOrder () != null)
tds.order (rel.getOrder ()); q.append (" "+rel.getOrder ());
} }
if (logSql) if (logSql)
app.logEvent ("### getNodes: "+tds.getSelectString()); app.logEvent ("### getNodes: "+q.toString());
if (rel.maxSize > 0) if (rel.maxSize > 0)
tds.fetchRecords (rel.maxSize); stmt.setMaxRows (rel.maxSize);
else
tds.fetchRecords ();
for (int i=0; i<tds.size (); i++) { ResultSet rs = stmt.executeQuery (q.toString ());
while (rs.next()) {
// create new Nodes. // create new Nodes.
Record rec = tds.getRecord (i); Node node = new Node (rel.otherType, rs, safe);
Node node = new Node (rel.otherType, rec, safe);
Key primKey = node.getKey (); Key primKey = node.getKey ();
retval.add (new NodeHandle (primKey)); retval.add (new NodeHandle (primKey));
// do we need to synchronize on primKey here? // do we need to synchronize on primKey here?
@ -784,8 +784,8 @@ public final class NodeManager {
} finally { } finally {
// tx.timer.endEvent ("getNodes "+home); // tx.timer.endEvent ("getNodes "+home);
if (tds != null) try { if (stmt != null) try {
tds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
return retval; return retval;
@ -804,42 +804,42 @@ public final class NodeManager {
} else { } else {
int missing = cache.containsKeys (keys); int missing = cache.containsKeys (keys);
if (missing > 0) { if (missing > 0) {
TableDataSet tds = new TableDataSet (dbm.getConnection (), Connection con = dbm.getConnection ();
dbm.getSchema (), Statement stmt = con.createStatement ();
dbm.getKeyDef ()); StringBuffer q = dbm.getSelect ();
try { try {
String idfield = rel.groupby != null ? rel.groupby : dbm.getIDField (); String idfield = rel.groupby != null ? rel.groupby : dbm.getIDField ();
boolean needsQuotes = dbm.needsQuotes (idfield); boolean needsQuotes = dbm.needsQuotes (idfield);
StringBuffer whereBuffer = new StringBuffer (idfield); q.append (" where ");
whereBuffer.append (" in ("); q.append (idfield);
q.append (" in (");
boolean first = true; boolean first = true;
for (int i=0; i<keys.length; i++) { for (int i=0; i<keys.length; i++) {
if (keys[i] != null) { if (keys[i] != null) {
if (!first) if (!first)
whereBuffer.append (','); q.append (',');
else else
first = false; first = false;
if (needsQuotes) { if (needsQuotes) {
whereBuffer.append ("'"); q.append ("'");
whereBuffer.append (escape (keys[i].getID ())); q.append (escape (keys[i].getID ()));
whereBuffer.append ("'"); q.append ("'");
} else { } else {
whereBuffer.append (keys[i].getID ()); q.append (keys[i].getID ());
} }
} }
} }
whereBuffer.append (')'); q.append (") ");
if (rel.groupby != null) { if (rel.groupby != null) {
whereBuffer.insert (0, rel.renderConstraints (home, home.getNonVirtualParent ())); q.append (rel.renderConstraints (home, home.getNonVirtualParent ()));
if (rel.order != null) if (rel.order != null)
whereBuffer.append (" ORDER BY "+rel.order); q.append (" ORDER BY "+rel.order);
} }
tds.where (whereBuffer.toString ());
if (logSql) if (logSql)
app.logEvent ("### prefetchNodes: "+tds.getSelectString()); app.logEvent ("### prefetchNodes: "+q.toString());
tds.fetchRecords (); ResultSet rs = stmt.executeQuery (q.toString());;
String groupbyProp = null; String groupbyProp = null;
HashMap groupbySubnodes = null; HashMap groupbySubnodes = null;
@ -852,10 +852,9 @@ public final class NodeManager {
if (rel.accessor != null && !rel.usesPrimaryKey ()) if (rel.accessor != null && !rel.usesPrimaryKey ())
accessProp = dbm.columnNameToProperty (rel.accessor); accessProp = dbm.columnNameToProperty (rel.accessor);
for (int i=0; i<tds.size (); i++) { while (rs.next ()) {
// create new Nodes. // create new Nodes.
Record rec = tds.getRecord (i); Node node = new Node (dbm, rs, safe);
Node node = new Node (dbm, rec, safe);
Key primKey = node.getKey (); Key primKey = node.getKey ();
// for grouped nodes, collect subnode lists for the intermediary // for grouped nodes, collect subnode lists for the intermediary
@ -906,8 +905,8 @@ public final class NodeManager {
} }
} }
} finally { } finally {
if (tds != null) try { if (stmt != null) try {
tds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
} }
@ -933,7 +932,7 @@ public final class NodeManager {
Connection con = rel.otherType.getConnection (); Connection con = rel.otherType.getConnection ();
String table = rel.otherType.getTableName (); String table = rel.otherType.getTableName ();
QueryDataSet qds = null; Statement stmt = null;
try { try {
String q = null; String q = null;
@ -948,18 +947,18 @@ public final class NodeManager {
if (logSql) if (logSql)
app.logEvent ("### countNodes: "+q); app.logEvent ("### countNodes: "+q);
qds = new QueryDataSet (con, q); stmt = con.createStatement();
qds.fetchRecords (); ResultSet rs = stmt.executeQuery (q);
if (qds.size () == 0) if (!rs.next())
retval = 0; retval = 0;
else else
retval = qds.getRecord (0).getValue (1).asInt (); retval = rs.getInt (1);
} finally { } finally {
// tx.timer.endEvent ("countNodes "+home); // tx.timer.endEvent ("countNodes "+home);
if (qds != null) try { if (stmt != null) try {
qds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
return rel.maxSize > 0 ? Math.min (rel.maxSize, retval) : retval; return rel.maxSize > 0 ? Math.min (rel.maxSize, retval) : retval;
@ -985,27 +984,26 @@ public final class NodeManager {
Connection con = rel.otherType.getConnection (); Connection con = rel.otherType.getConnection ();
String table = rel.otherType.getTableName (); String table = rel.otherType.getTableName ();
QueryDataSet qds = null; Statement stmt = null;
try { try {
String q = "SELECT "+namefield+" FROM "+table+" ORDER BY "+namefield; String q = "SELECT "+namefield+" FROM "+table+" ORDER BY "+namefield;
qds = new QueryDataSet (con, q); stmt = con.createStatement ();
if (logSql) if (logSql)
app.logEvent ("### getPropertyNames: "+qds.getSelectString()); app.logEvent ("### getPropertyNames: "+q);
qds.fetchRecords (); ResultSet rs = stmt.executeQuery (q);
for (int i=0; i<qds.size (); i++) { while (rs.next()) {
Record rec = qds.getRecord (i); String n = rs.getString (1);
String n = rec.getValue (1).asString ();
if (n != null) if (n != null)
retval.addElement (n); retval.addElement (n);
} }
} finally { } finally {
// tx.timer.endEvent ("getNodeIDs "+home); // tx.timer.endEvent ("getNodeIDs "+home);
if (qds != null) try { if (stmt != null) try {
qds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
return retval; return retval;
@ -1031,26 +1029,31 @@ public final class NodeManager {
} else { } else {
String idfield =dbm.getIDField (); String idfield =dbm.getIDField ();
TableDataSet tds = null; Statement stmt = null;
try { try {
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ()); Connection con = dbm.getConnection ();
tds.where (idfield+" = "+kstr); stmt = con.createStatement ();
StringBuffer q = dbm.getSelect ();
q.append (" where ");
q.append (idfield);
q.append (" = ");
q.append (kstr);
if (logSql) if (logSql)
app.logEvent ("### getNodeByKey: "+tds.getSelectString()); app.logEvent ("### getNodeByKey: "+q.toString());
tds.fetchRecords (); ResultSet rs = stmt.executeQuery (q.toString());
if (tds.size () == 0) if (!rs.next ())
return null; return null;
if (tds.size () > 1) if (!rs.isLast ())
throw new RuntimeException ("More than one value returned by query."); throw new RuntimeException ("More than one value returned by query.");
Record rec = tds.getRecord (0); node = new Node (dbm, rs, safe);
node = new Node (dbm, rec, safe);
} finally { } finally {
if (tds != null) try { if (stmt != null) try {
tds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
} }
@ -1086,35 +1089,35 @@ public final class NodeManager {
return node; return node;
} else { } else {
TableDataSet tds = null; Statement stmt = null;
try { try {
DbMapping dbm = rel.otherType; DbMapping dbm = rel.otherType;
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ()); Connection con = dbm.getConnection ();
StringBuffer q = dbm.getSelect ();
if (home.getSubnodeRelation () != null) { if (home.getSubnodeRelation () != null) {
// combine our key with the constraints in the manually set subnode relation // combine our key with the constraints in the manually set subnode relation
StringBuffer where = new StringBuffer (); q.append (home.getSubnodeRelation ());
where.append (rel.accessor); q.append (" and ");
where.append (" = '"); q.append (rel.accessor);
where.append (escape(kstr)); q.append (" = '");
where.append ("' AND "); q.append (escape(kstr));
where.append (home.getSubnodeRelation ().trim().substring(5).trim()); q.append ("'");
tds.where (where.toString ()); } else {
} else q.append (" where ");
tds.where (rel.buildQuery (home, home.getNonVirtualParent (), kstr, "", false)); q.append (rel.buildQuery (home, home.getNonVirtualParent (), kstr, "", false));
}
if (logSql) if (logSql)
app.logEvent ("### getNodeByRelation: "+tds.getSelectString()); app.logEvent ("### getNodeByRelation: "+q.toString());
tds.fetchRecords (); stmt = con.createStatement ();
ResultSet rs = stmt.executeQuery (q.toString());
if (tds.size () == 0) if (!rs.next ())
return null; return null;
if (tds.size () > 1) if (!rs.isLast ())
throw new RuntimeException ("More than one value returned by query."); throw new RuntimeException ("More than one value returned by query.");
Record rec = tds.getRecord (0); node = new Node (rel.otherType, rs, safe);
node = new Node (rel.otherType, rec, safe);
// Check if node is already cached with primary Key. // Check if node is already cached with primary Key.
if (!rel.usesPrimaryKey()) { if (!rel.usesPrimaryKey()) {
@ -1126,8 +1129,8 @@ public final class NodeManager {
} }
} finally { } finally {
if (tds != null) try { if (stmt != null) try {
tds.close (); stmt.close ();
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
} }

View file

@ -35,6 +35,9 @@ public final class Relation {
// the DbMapping of the prototype we link to, unless this is a "primitive" (non-object) relation // the DbMapping of the prototype we link to, unless this is a "primitive" (non-object) relation
DbMapping otherType; DbMapping otherType;
// the column type, as defined in java.sql.Types
int columnType;
// if this relation defines a virtual node, we need to provide a DbMapping for these virtual nodes // if this relation defines a virtual node, we need to provide a DbMapping for these virtual nodes
DbMapping virtualMapping; DbMapping virtualMapping;
@ -240,6 +243,14 @@ public final class Relation {
return propName; return propName;
} }
public void setColumnType (int ct) {
columnType = ct;
}
public int getColumnType () {
return columnType;
}
/** /**
* Add a constraint to the current list of constraints * Add a constraint to the current list of constraints