You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by br...@apache.org on 2003/03/01 23:19:02 UTC
cvs commit: db-ojb/src/java/org/apache/ojb/broker/accesslayer StatementManager.java
brj 2003/03/01 14:19:02
Modified: src/java/org/apache/ojb/broker/accesslayer
StatementManager.java
Log:
moved get...values to BrokerHelper
Revision Changes Path
1.22 +695 -748 db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
Index: StatementManager.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- StatementManager.java 2 Feb 2003 03:39:19 -0000 1.21
+++ StatementManager.java 1 Mar 2003 22:19:02 -0000 1.22
@@ -54,13 +54,23 @@
* <http://www.apache.org/>.
*/
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerSQLException;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
-import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.platforms.PlatformException;
import org.apache.ojb.broker.platforms.PlatformFactory;
@@ -78,17 +88,6 @@
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Types;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.WeakHashMap;
-
/**
* manages JDBC Connection and Statement resources.
*
@@ -97,740 +96,688 @@
*/
public class StatementManager implements StatementManagerIF
{
- private Logger log = LoggerFactory.getLogger(StatementManager.class);
+ private Logger log = LoggerFactory.getLogger(StatementManager.class);
- /** internal table of StatementForClass objects */
- private Map statementTable = new WeakHashMap();
- /** the associated broker */
- private final PersistenceBroker broker;
- private Platform platform;
- /**
- * Used when OJB run in JBoss
- * @todo Find a better solution to handle OJB within JBoss
- * --> the JCA implementation should solve this problem
- */
- private boolean m_eagerRelease;
- private ConnectionManagerIF conMan;
-
- public StatementManager(final PersistenceBroker pBroker)
- {
- this.broker = pBroker;
- this.conMan = broker.serviceConnectionManager();
- m_eagerRelease = conMan.getConnectionDescriptor().getEagerRelease();
- platform = PlatformFactory.getPlatformFor(conMan.getConnectionDescriptor());
- }
-
- /**
- * return a StatementsForClass object for the given ClassDescriptor\
- * Note; not important to synchronize completely as a threading issue in this code
- * will only result in a little extra code being executed
- */
- protected StatementsForClassIF getStatementsForClass(ClassDescriptor cds)
- throws PersistenceBrokerException
- {
- StatementsForClassIF sfc = (StatementsForClassIF) statementTable.get(cds);
- if (sfc == null)
- {
- synchronized (statementTable)
- {
- sfc = (StatementsForClassIF) new StatementsForClassImpl(conMan.getConnectionDescriptor(), cds);
- statementTable.put(cds, sfc);
- }
- }
- return sfc;
- }
-
- public void closeResources(Statement stmt, ResultSet rs)
- {
- if (log.isDebugEnabled()) log.debug("closeResources was called");
- try
- {
- platform.beforeStatementClose(stmt, rs);
- //close statement on wrapped statement class, or real statement
- if (stmt != null)
- {
- //log.info("## close: "+stmt);
- stmt.close();
-
- /*
- *********************************************
- special stuff for OJB within JBoss
- ********************************************
- */
- if (m_eagerRelease)
- {
- conMan.releaseConnection();
- }
-
- }
- platform.afterStatementClose(stmt, rs);
- }
- catch (PlatformException e)
- {
- log.error("Platform dependent operation failed", e);
- }
- catch (SQLException ignored)
- {
- if (log.isDebugEnabled()) log.debug("Statement closing failed", ignored);
- }
- }
-
- /**
- * binds the Identities Primary key values to the statement
- */
- public void bindDelete(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws java.sql.SQLException
- {
- if (cld == null)
- {
- cld = broker.getClassDescriptor(oid.getObjectsClass());
- }
- for (int i = 0; i < oid.getPrimaryKeyValues().length; i++)
- {
- platform.setObjectForStatement(stmt, i + 1, oid.getPrimaryKeyValues()[i], SqlHelper.getSqlTypePk(cld, i));
- }
- }
-
- /**
- * binds the objects primary key and locking values to the statement, BRJ
- */
- public void bindDelete(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
- {
- int index = 1;
- Object[] values, currentLockingValues;
-
- currentLockingValues = cld.getCurrentLockingValues(obj);
-
- // parameters for WHERE-clause pk
- values = broker.serviceBrokerHelper().getKeyValues(cld, obj);
- for (int i = 0; i < values.length; i++)
- {
- platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypePk(cld, i));
- index++;
- }
-
- // parameters for WHERE-clause locking
- values = currentLockingValues;
- for (int i = 0; i < values.length; i++)
- {
- platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeLocking(cld, i));
- index++;
- }
- }
-
- /**
- * bind a value
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param attributeName the query attribute to bind
- * @param value the value to bind
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindStatementValue(
- PreparedStatement stmt,
- int index,
- Object value,
- ClassDescriptor cld,
- FieldDescriptor fld)
- throws SQLException
- {
- // if value is a subQuery bind it
- if (value instanceof Query)
- {
- Query subQuery = (Query) value;
- if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
- {
- return bindStatement(
- stmt,
- subQuery.getCriteria(),
- cld.getRepository().getDescriptorFor(subQuery.getSearchClass()),
- index);
- }
- return index;
- }
-
- // if query has criteria, bind them
- if (fld != null)
- {
- // BRJ: use field conversions and platform
- if (value != null)
- {
- platform.setObjectForStatement(
- stmt,
- index,
- fld.getFieldConversion().javaToSql(value),
- fld.getColumnJdbcType());
- }
- else
- {
- platform.setNullForStatement(stmt, index, fld.getColumnJdbcType());
- }
- }
- else
- {
- // BRJ: No FieldDescriptor found
- if (value != null)
- {
- stmt.setObject(index, value);
- }
- else
- {
- stmt.setNull(index, Types.NULL);
- }
- }
-
- return ++index; // increment before return
- }
-
- /**
- * bind SelectionCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld)
- throws SQLException
- {
- FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
- return bindStatementValue(stmt, index, crit.getValue(), cld, fld);
- }
-
- /**
- * bind NullCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, NullCriteria crit) throws SQLException
- {
- return index;
- }
-
- /**
- * bind FieldCriteria
- * @param stmt , the PreparedStatement
- * @param index , the position of the parameter to bind
- * @param crit , the Criteria containing the parameter
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, FieldCriteria crit)
- throws SQLException
- {
- return index;
- }
-
- /**
- * bind ColumnCriteria
- * @param stmt , the PreparedStatement
- * @param index , the position of the parameter to bind
- * @param crit , the Criteria containing the parameter
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, ColumnCriteria crit)
- throws SQLException
- {
- return index;
- }
-
- /**
- * bind SqlCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, SqlCriteria crit) throws SQLException
- {
- return index;
- }
-
- /**
- * bind BetweenCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, BetweenCriteria crit, ClassDescriptor cld)
- throws SQLException
- {
- FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
- index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
- return bindStatementValue(stmt, index, crit.getValue2(), cld, fld);
- }
-
- /**
- * bind InCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindStatement(PreparedStatement stmt, int index, InCriteria crit, ClassDescriptor cld) throws SQLException
- {
- FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
- if (crit.getValue() instanceof Collection)
- {
- Collection values = (Collection) crit.getValue();
- Iterator iter = values.iterator();
-
- while (iter.hasNext())
- {
- index = bindStatementValue(stmt, index, iter.next(), cld, fld);
- }
- }
- else
- {
- index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
- }
- return index;
- }
-
- /**
- * bind ExistsCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindStatement(
- PreparedStatement stmt,
- int index,
- ExistsCriteria crit,
- ClassDescriptor cld)
- throws SQLException
- {
- Query subQuery = (Query) crit.getValue();
-
- // if query has criteria, bind them
- if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
- {
- return bindStatement(
- stmt,
- subQuery.getCriteria(),
- cld.getRepository().getDescriptorFor(subQuery.getSearchClass()),
- index);
-
- // otherwise, just ignore it
- }
- else
- {
- return index;
- }
- }
-
- /**
- * bind a Query based Select Statement
- */
- public int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int param)
- throws SQLException
- {
- if (crit != null)
- {
- Enumeration e = crit.getElements();
-
- while (e.hasMoreElements())
- {
- Object o = e.nextElement();
- if (o instanceof Criteria)
- {
- Criteria pc = (Criteria) o;
- param = bindStatement(stmt, pc, cld, param);
- }
- else
- {
- SelectionCriteria c = (SelectionCriteria) o;
-
- // BRJ : bind once for the criterion's main class
- param = bindSelectionCriteria(stmt, param, c, cld);
-
- // BRJ : and once for each extent
- for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
- {
- param = bindSelectionCriteria(stmt, param, c, cld);
- }
- }
- }
- }
- return param;
- }
-
- /**
- * bind SelectionCriteria
- * @param stmt the PreparedStatement
- * @param index the position of the parameter to bind
- * @param crit the Criteria containing the parameter
- * @param cld the ClassDescriptor
- * @return next index for PreparedStatement
- */
- private int bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld)
- throws SQLException
- {
- if (crit instanceof NullCriteria)
- index = bindStatement(stmt, index, (NullCriteria) crit);
- else if (crit instanceof BetweenCriteria)
- index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
- else if (crit instanceof InCriteria)
- index = bindStatement(stmt, index, (InCriteria) crit, cld);
- else if (crit instanceof SqlCriteria)
- index = bindStatement(stmt, index, (SqlCriteria) crit);
- else if (crit instanceof FieldCriteria)
- index = bindStatement(stmt, index, (FieldCriteria) crit);
- else if (crit instanceof ColumnCriteria)
- index = bindStatement(stmt, index, (ColumnCriteria) crit);
- else if (crit instanceof ExistsCriteria)
- index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
- else
- index = bindStatement(stmt, index, crit, cld);
-
- return index;
- }
-
-
- /**
- * binds the values of the object obj to the statements parameters
- */
- public void bindInsert(PreparedStatement stmt, ClassDescriptor cld, Object obj)
- throws java.sql.SQLException
- {
- Object[] values;
- cld.updateLockingValues(obj); // BRJ : provide useful defaults for locking fields
-
- values = getAllValues(cld, obj);
- for (int i = 0; i < values.length; i++)
- {
- Object val = values[i];
- if (val != null)
- {
- platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypeAll(cld, i));
- }
- else
- {
- platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypeAll(cld, i));
- }
-
- }
- }
-
- /**
- * binds the Identities Primary key values to the statement
- */
- public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException
- {
- if (cld == null)
- {
- cld = broker.getClassDescriptor(oid.getObjectsClass());
- }
- int i = 0;
- try
- {
- Object[] values = oid.getPrimaryKeyValues();
- for (i = 0; i < values.length; i++)
- {
- Object val = values[i];
- if (val != null)
- {
- platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypePk(cld, i));
- }
- else
- {
- platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypePk(cld, i));
- }
- }
- }
- catch (SQLException e)
- {
- log.error(
- "bindSelect failed for: "
- + oid.toString()
- + ", PK: "
- + i
- + ", value: "
- + oid.getPrimaryKeyValues()[i]);
- throw e;
- }
- }
-
- /**
- * binds the values of the object obj to the statements parameters
- */
- public void bindUpdate(PreparedStatement stmt, ClassDescriptor cld, Object obj)
- throws java.sql.SQLException
- {
- int index = 1;
- Object[] values, currentLockingValues;
-
- currentLockingValues = cld.getCurrentLockingValues(obj);
- cld.updateLockingValues(obj); // BRJ
- values = getNonKeyValues(broker, cld, obj);
-
- // parameters for SET-clause
- for (int i = 0; i < values.length; i++)
- {
- Object val = values[i];
- if (val != null)
- platform.setObjectForStatement(stmt, index, val, SqlHelper.getSqlTypeNonPk(cld, i));
- else
- platform.setNullForStatement(stmt, index, SqlHelper.getSqlTypeNonPk(cld, i));
- index++;
- }
- // parameters for WHERE-clause pk
- values = broker.serviceBrokerHelper().getKeyValues(cld, obj);
- for (int i = 0; i < values.length; i++)
- {
- Object val = values[i];
- if (val != null)
- stmt.setObject(index, values[i]);
- else
- stmt.setNull(index, SqlHelper.getSqlTypePk(cld, i));
-
- index++;
- }
- // parameters for WHERE-clause locking
- values = currentLockingValues;
- for (int i = 0; i < values.length; i++)
- {
- Object val = values[i];
- if (val != null)
- stmt.setObject(index, values[i]);
- else
- stmt.setNull(index, SqlHelper.getSqlTypeNonPk(cld, i));
-
- index++;
- }
- }
-
- /**
- * binds the given array of values (if not null) starting from the given
- * parameter index
- * @return the next parameter index
- */
- public int bindValues(PreparedStatement stmt, Object[] values, int index)
- throws SQLException
- {
- if (values != null)
- {
- for (int i = 0; i < values.length; i++)
- {
- platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeByValue(values[i]));
- index++;
- }
- }
- return index;
- }
-
- /**
- * return a prepared DELETE Statement fitting for the given ClassDescriptor
- */
- public PreparedStatement getDeleteStatement(ClassDescriptor cld)
- throws PersistenceBrokerSQLException, PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cld).getDeleteStmt(broker.serviceConnectionManager().getConnection());
- }
- catch (SQLException e)
- {
- throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * return a generic Statement for the given ClassDescriptor.
- * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
- */
- public Statement getGenericStatement(ClassDescriptor cds, boolean scrollable) throws PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cds).getGenericStmt(conMan.getConnection(), scrollable);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * return a prepared Insert Statement fitting for the given ClassDescriptor
- */
- public PreparedStatement getInsertStatement(ClassDescriptor cds)
- throws PersistenceBrokerSQLException, PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cds).getInsertStmt(conMan.getConnection());
- }
- catch (SQLException e)
- {
- throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * return a generic Statement for the given ClassDescriptor
- */
- public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql, boolean scrollable)
- throws PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cds).getPreparedStmt(conMan.getConnection(), sql, scrollable);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * return a prepared Select Statement for the given ClassDescriptor
- */
- public PreparedStatement getSelectByPKStatement(ClassDescriptor cds)
- throws PersistenceBrokerSQLException, PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cds).getSelectByPKStmt(conMan.getConnection());
- }
- catch (SQLException e)
- {
- throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * return a prepared Update Statement fitting to the given ClassDescriptor
- */
- public PreparedStatement getUpdateStatement(ClassDescriptor cds)
- throws PersistenceBrokerSQLException, PersistenceBrokerException
- {
- try
- {
- return getStatementsForClass(cds).getUpdateStmt(conMan.getConnection());
- }
- catch (SQLException e)
- {
- throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
- }
- catch (LookupException e)
- {
- throw new PersistenceBrokerException(
- "Used ConnectionManager instance could not obtain a connection", e);
- }
- }
-
- /**
- * returns an array containing values for all the Objects attribute
- * @throws MetadataException if tehre is an erros accessing obj field values
- */
- protected Object[] getAllValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
- {
- FieldDescriptor[] allFields = cld.getFieldDescriptions();
- Object[] result = new Object[allFields.length];
-
- for (int i = 0; i < allFields.length; i++)
- {
- FieldDescriptor fmd = allFields[i];
- PersistentField f = fmd.getPersistentField();
- Object cv = f.get(obj);
-
- // handle autoincrement attributes if not filled
- if (fmd.isAutoIncrement())
- {
- cv = broker.serviceBrokerHelper().getAutoIncrementValue(fmd, obj, cv);
- }
-
- // apply type and value mapping
- cv = fmd.getFieldConversion().javaToSql(cv);
- result[i] = cv;
- }
- return result;
- }
-
- /**
- * returns an Array with an Objects NON-PK VALUES
- * @throws MetadataException if there is an erros accessing o field values
- */
- protected Object[] getNonKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object o) throws PersistenceBrokerException
- {
- FieldDescriptor[] nonPkFields = cld.getNonPkFields();
- Object[] result = new Object[nonPkFields.length];
-
- for (int i = 0; i < result.length; i++)
- {
- FieldDescriptor fmd = nonPkFields[i];
- PersistentField f = fmd.getPersistentField();
- Object cv = f.get(o);
-
- // handle autoincrement attributes if not filled
- if (fmd.isAutoIncrement())
- {
- cv = broker.serviceBrokerHelper().getAutoIncrementValue(fmd, o, cv);
- }
-
- // apply type and value conversion
- cv = fmd.getFieldConversion().javaToSql(cv);
- result[i] = cv;
- }
- return result;
- }
-
- /**
- * MBAIRD: I would prefer to remove statement caching completely, but instead we
- * deal with edge cases.
- */
- private void closeIfNotCached(Statement stmt)
- {
- boolean doClose = true;
- synchronized (statementTable)
- {
- for (Iterator it = statementTable.values().iterator(); it.hasNext();)
- {
- StatementsForClassIF sfc = (StatementsForClassIF) it.next();
- if (sfc != null)
- {
- if (sfc.isCached(stmt))
- {
- doClose = false;
- break;
- }
- }
- }
- }
- if (doClose)
- {
- try
- {
- stmt.close();
- }
- catch (SQLException ignored)
- {
- LoggerFactory.getDefaultLogger().warn("closing statement had error: " + ignored.getMessage());
- }
- }
- }
+ /** internal table of StatementForClass objects */
+ private Map statementTable = new WeakHashMap();
+ /** the associated broker */
+ private final PersistenceBroker broker;
+ private Platform platform;
+ /**
+ * Used when OJB run in JBoss
+ * @todo Find a better solution to handle OJB within JBoss
+ * --> the JCA implementation should solve this problem
+ */
+ private boolean m_eagerRelease;
+ private ConnectionManagerIF conMan;
+
+ public StatementManager(final PersistenceBroker pBroker)
+ {
+ this.broker = pBroker;
+ this.conMan = broker.serviceConnectionManager();
+ m_eagerRelease = conMan.getConnectionDescriptor().getEagerRelease();
+ platform = PlatformFactory.getPlatformFor(conMan.getConnectionDescriptor());
+ }
+
+ /**
+ * return a StatementsForClass object for the given ClassDescriptor\
+ * Note; not important to synchronize completely as a threading issue in this code
+ * will only result in a little extra code being executed
+ */
+ protected StatementsForClassIF getStatementsForClass(ClassDescriptor cds) throws PersistenceBrokerException
+ {
+ StatementsForClassIF sfc = (StatementsForClassIF) statementTable.get(cds);
+ if (sfc == null)
+ {
+ synchronized (statementTable)
+ {
+ sfc = (StatementsForClassIF) new StatementsForClassImpl(conMan.getConnectionDescriptor(), cds);
+ statementTable.put(cds, sfc);
+ }
+ }
+ return sfc;
+ }
+
+ public void closeResources(Statement stmt, ResultSet rs)
+ {
+ if (log.isDebugEnabled())
+ log.debug("closeResources was called");
+ try
+ {
+ platform.beforeStatementClose(stmt, rs);
+ //close statement on wrapped statement class, or real statement
+ if (stmt != null)
+ {
+ //log.info("## close: "+stmt);
+ stmt.close();
+
+ /*
+ *********************************************
+ special stuff for OJB within JBoss
+ ********************************************
+ */
+ if (m_eagerRelease)
+ {
+ conMan.releaseConnection();
+ }
+
+ }
+ platform.afterStatementClose(stmt, rs);
+ }
+ catch (PlatformException e)
+ {
+ log.error("Platform dependent operation failed", e);
+ }
+ catch (SQLException ignored)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Statement closing failed", ignored);
+ }
+ }
+
+ /**
+ * binds the Identities Primary key values to the statement
+ */
+ public void bindDelete(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws java.sql.SQLException
+ {
+ Object[] values = null;
+ int i = 0;
+
+ if (cld == null)
+ {
+ cld = broker.getClassDescriptor(oid.getObjectsClass());
+ }
+
+ values = getKeyValues(broker, cld, oid);
+
+ try
+ {
+ for (i = 0; i < values.length; i++)
+ {
+ platform.setObjectForStatement(stmt, i + 1, values[i], SqlHelper.getSqlTypePk(cld, i));
+ }
+ }
+ catch (SQLException e)
+ {
+ log.error("bindDelete failed for: " + oid.toString() + ", PK: " + i + ", value: " + values[i]);
+ throw e;
+ }
+ }
+
+ /**
+ * binds the objects primary key and locking values to the statement, BRJ
+ */
+ public void bindDelete(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
+ {
+ int index = 1;
+ Object[] values, currentLockingValues;
+
+ currentLockingValues = cld.getCurrentLockingValues(obj);
+
+ // parameters for WHERE-clause pk
+ values = getKeyValues(broker, cld, obj);
+ for (int i = 0; i < values.length; i++)
+ {
+ platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypePk(cld, i));
+ index++;
+ }
+
+ // parameters for WHERE-clause locking
+ values = currentLockingValues;
+ for (int i = 0; i < values.length; i++)
+ {
+ platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeLocking(cld, i));
+ index++;
+ }
+ }
+
+ /**
+ * bind a value
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param attributeName the query attribute to bind
+ * @param value the value to bind
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindStatementValue(PreparedStatement stmt, int index, Object value, ClassDescriptor cld, FieldDescriptor fld)
+ throws SQLException
+ {
+ // if value is a subQuery bind it
+ if (value instanceof Query)
+ {
+ Query subQuery = (Query) value;
+ if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
+ {
+ return bindStatement(stmt, subQuery.getCriteria(), cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
+ }
+ return index;
+ }
+
+ // if query has criteria, bind them
+ if (fld != null)
+ {
+ // BRJ: use field conversions and platform
+ if (value != null)
+ {
+ platform.setObjectForStatement(stmt, index, fld.getFieldConversion().javaToSql(value), fld.getColumnJdbcType());
+ }
+ else
+ {
+ platform.setNullForStatement(stmt, index, fld.getColumnJdbcType());
+ }
+ }
+ else
+ {
+ // BRJ: No FieldDescriptor found
+ if (value != null)
+ {
+ stmt.setObject(index, value);
+ }
+ else
+ {
+ stmt.setNull(index, Types.NULL);
+ }
+ }
+
+ return ++index; // increment before return
+ }
+
+ /**
+ * bind SelectionCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
+ {
+ FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
+ return bindStatementValue(stmt, index, crit.getValue(), cld, fld);
+ }
+
+ /**
+ * bind NullCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, NullCriteria crit) throws SQLException
+ {
+ return index;
+ }
+
+ /**
+ * bind FieldCriteria
+ * @param stmt , the PreparedStatement
+ * @param index , the position of the parameter to bind
+ * @param crit , the Criteria containing the parameter
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, FieldCriteria crit) throws SQLException
+ {
+ return index;
+ }
+
+ /**
+ * bind ColumnCriteria
+ * @param stmt , the PreparedStatement
+ * @param index , the position of the parameter to bind
+ * @param crit , the Criteria containing the parameter
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, ColumnCriteria crit) throws SQLException
+ {
+ return index;
+ }
+
+ /**
+ * bind SqlCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, SqlCriteria crit) throws SQLException
+ {
+ return index;
+ }
+
+ /**
+ * bind BetweenCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, BetweenCriteria crit, ClassDescriptor cld) throws SQLException
+ {
+ FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
+ index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
+ return bindStatementValue(stmt, index, crit.getValue2(), cld, fld);
+ }
+
+ /**
+ * bind InCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, InCriteria crit, ClassDescriptor cld) throws SQLException
+ {
+ FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
+ if (crit.getValue() instanceof Collection)
+ {
+ Collection values = (Collection) crit.getValue();
+ Iterator iter = values.iterator();
+
+ while (iter.hasNext())
+ {
+ index = bindStatementValue(stmt, index, iter.next(), cld, fld);
+ }
+ }
+ else
+ {
+ index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
+ }
+ return index;
+ }
+
+ /**
+ * bind ExistsCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindStatement(PreparedStatement stmt, int index, ExistsCriteria crit, ClassDescriptor cld) throws SQLException
+ {
+ Query subQuery = (Query) crit.getValue();
+
+ // if query has criteria, bind them
+ if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
+ {
+ return bindStatement(stmt, subQuery.getCriteria(), cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
+
+ // otherwise, just ignore it
+ }
+ else
+ {
+ return index;
+ }
+ }
+
+ /**
+ * bind a Query based Select Statement
+ */
+ public int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int param) throws SQLException
+ {
+ if (crit != null)
+ {
+ Enumeration e = crit.getElements();
+
+ while (e.hasMoreElements())
+ {
+ Object o = e.nextElement();
+ if (o instanceof Criteria)
+ {
+ Criteria pc = (Criteria) o;
+ param = bindStatement(stmt, pc, cld, param);
+ }
+ else
+ {
+ SelectionCriteria c = (SelectionCriteria) o;
+
+ // BRJ : bind once for the criterion's main class
+ param = bindSelectionCriteria(stmt, param, c, cld);
+
+ // BRJ : and once for each extent
+ for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
+ {
+ param = bindSelectionCriteria(stmt, param, c, cld);
+ }
+ }
+ }
+ }
+ return param;
+ }
+
+ /**
+ * bind SelectionCriteria
+ * @param stmt the PreparedStatement
+ * @param index the position of the parameter to bind
+ * @param crit the Criteria containing the parameter
+ * @param cld the ClassDescriptor
+ * @return next index for PreparedStatement
+ */
+ private int bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
+ {
+ if (crit instanceof NullCriteria)
+ index = bindStatement(stmt, index, (NullCriteria) crit);
+ else if (crit instanceof BetweenCriteria)
+ index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
+ else if (crit instanceof InCriteria)
+ index = bindStatement(stmt, index, (InCriteria) crit, cld);
+ else if (crit instanceof SqlCriteria)
+ index = bindStatement(stmt, index, (SqlCriteria) crit);
+ else if (crit instanceof FieldCriteria)
+ index = bindStatement(stmt, index, (FieldCriteria) crit);
+ else if (crit instanceof ColumnCriteria)
+ index = bindStatement(stmt, index, (ColumnCriteria) crit);
+ else if (crit instanceof ExistsCriteria)
+ index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
+ else
+ index = bindStatement(stmt, index, crit, cld);
+
+ return index;
+ }
+
+ /**
+ * binds the values of the object obj to the statements parameters
+ */
+ public void bindInsert(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
+ {
+ Object[] values;
+ cld.updateLockingValues(obj); // BRJ : provide useful defaults for locking fields
+
+ values = getAllValues(cld, obj);
+ for (int i = 0; i < values.length; i++)
+ {
+ Object val = values[i];
+ if (val != null)
+ {
+ platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypeAll(cld, i));
+ }
+ else
+ {
+ platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypeAll(cld, i));
+ }
+
+ }
+ }
+
+ /**
+ * binds the Identities Primary key values to the statement
+ */
+ public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException
+ {
+ Object[] values = null;
+ int i = 0;
+
+ if (cld == null)
+ {
+ cld = broker.getClassDescriptor(oid.getObjectsClass());
+ }
+ try
+ {
+ values = getKeyValues(broker, cld, oid);
+ for (i = 0; i < values.length; i++)
+ {
+ Object val = values[i];
+ if (val != null)
+ {
+ platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypePk(cld, i));
+ }
+ else
+ {
+ platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypePk(cld, i));
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ log.error("bindSelect failed for: " + oid.toString() + ", PK: " + i + ", value: " + values[i]);
+ throw e;
+ }
+ }
+
+ /**
+ * binds the values of the object obj to the statements parameters
+ */
+ public void bindUpdate(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
+ {
+ int index = 1;
+ Object[] values, currentLockingValues;
+
+ currentLockingValues = cld.getCurrentLockingValues(obj);
+ cld.updateLockingValues(obj); // BRJ
+ values = getNonKeyValues(broker, cld, obj);
+
+ // parameters for SET-clause
+ for (int i = 0; i < values.length; i++)
+ {
+ Object val = values[i];
+ if (val != null)
+ platform.setObjectForStatement(stmt, index, val, SqlHelper.getSqlTypeNonPk(cld, i));
+ else
+ platform.setNullForStatement(stmt, index, SqlHelper.getSqlTypeNonPk(cld, i));
+ index++;
+ }
+ // parameters for WHERE-clause pk
+ values = getKeyValues(broker, cld, obj);
+ for (int i = 0; i < values.length; i++)
+ {
+ Object val = values[i];
+ if (val != null)
+ stmt.setObject(index, values[i]);
+ else
+ stmt.setNull(index, SqlHelper.getSqlTypePk(cld, i));
+
+ index++;
+ }
+ // parameters for WHERE-clause locking
+ values = currentLockingValues;
+ for (int i = 0; i < values.length; i++)
+ {
+ Object val = values[i];
+ if (val != null)
+ stmt.setObject(index, values[i]);
+ else
+ stmt.setNull(index, SqlHelper.getSqlTypeNonPk(cld, i));
+
+ index++;
+ }
+ }
+
+ /**
+ * binds the given array of values (if not null) starting from the given
+ * parameter index
+ * @return the next parameter index
+ */
+ public int bindValues(PreparedStatement stmt, Object[] values, int index) throws SQLException
+ {
+ if (values != null)
+ {
+ for (int i = 0; i < values.length; i++)
+ {
+ platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeByValue(values[i]));
+ index++;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * return a prepared DELETE Statement fitting for the given ClassDescriptor
+ */
+ public PreparedStatement getDeleteStatement(ClassDescriptor cld) throws PersistenceBrokerSQLException, PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cld).getDeleteStmt(broker.serviceConnectionManager().getConnection());
+ }
+ catch (SQLException e)
+ {
+ throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * return a generic Statement for the given ClassDescriptor.
+ * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
+ */
+ public Statement getGenericStatement(ClassDescriptor cds, boolean scrollable) throws PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cds).getGenericStmt(conMan.getConnection(), scrollable);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * return a prepared Insert Statement fitting for the given ClassDescriptor
+ */
+ public PreparedStatement getInsertStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cds).getInsertStmt(conMan.getConnection());
+ }
+ catch (SQLException e)
+ {
+ throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * return a generic Statement for the given ClassDescriptor
+ */
+ public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql, boolean scrollable) throws PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cds).getPreparedStmt(conMan.getConnection(), sql, scrollable);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * return a prepared Select Statement for the given ClassDescriptor
+ */
+ public PreparedStatement getSelectByPKStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cds).getSelectByPKStmt(conMan.getConnection());
+ }
+ catch (SQLException e)
+ {
+ throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * return a prepared Update Statement fitting to the given ClassDescriptor
+ */
+ public PreparedStatement getUpdateStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
+ {
+ try
+ {
+ return getStatementsForClass(cds).getUpdateStmt(conMan.getConnection());
+ }
+ catch (SQLException e)
+ {
+ throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
+ }
+ catch (LookupException e)
+ {
+ throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
+ }
+ }
+
+ /**
+ * returns an array containing values for all the Objects attribute
+ * @throws MetadataException if tehre is an erros accessing obj field values
+ */
+ protected Object[] getAllValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
+ {
+ return broker.serviceBrokerHelper().getAllValues(cld, obj);
+ }
+
+ /**
+ * returns an Array with an Objects PK VALUES
+ * @throws MetadataException if there is an erros accessing o field values
+ */
+ protected Object[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
+ {
+ return broker.serviceBrokerHelper().getKeyValues(cld, obj);
+ }
+
+ /**
+ * returns an Array with an Identities PK VALUES
+ * @throws MetadataException if there is an erros accessing o field values
+ */
+ protected Object[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Identity oid) throws PersistenceBrokerException
+ {
+ return oid.getPrimaryKeyValues();
+ }
+
+ /**
+ * returns an Array with an Objects NON-PK VALUES
+ * @throws MetadataException if there is an erros accessing o field values
+ */
+ protected Object[] getNonKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
+ {
+ return broker.serviceBrokerHelper().getNonKeyValues(cld, obj);
+ }
+
+ /**
+ * MBAIRD: I would prefer to remove statement caching completely, but instead we
+ * deal with edge cases.
+ */
+ private void closeIfNotCached(Statement stmt)
+ {
+ boolean doClose = true;
+ synchronized (statementTable)
+ {
+ for (Iterator it = statementTable.values().iterator(); it.hasNext();)
+ {
+ StatementsForClassIF sfc = (StatementsForClassIF) it.next();
+ if (sfc != null)
+ {
+ if (sfc.isCached(stmt))
+ {
+ doClose = false;
+ break;
+ }
+ }
+ }
+ }
+ if (doClose)
+ {
+ try
+ {
+ stmt.close();
+ }
+ catch (SQLException ignored)
+ {
+ LoggerFactory.getDefaultLogger().warn("closing statement had error: " + ignored.getMessage());
+ }
+ }
+ }
}