Coverage Report - org.apache.ojb.broker.accesslayer.StatementManager
 
Classes in this File Line Coverage Branch Coverage Complexity
StatementManager
N/A
N/A
3.71
 
 1  
 package org.apache.ojb.broker.accesslayer;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.sql.CallableStatement;
 19  
 import java.sql.PreparedStatement;
 20  
 import java.sql.ResultSet;
 21  
 import java.sql.SQLException;
 22  
 import java.sql.Statement;
 23  
 import java.sql.Types;
 24  
 import java.util.Collection;
 25  
 import java.util.Enumeration;
 26  
 import java.util.Iterator;
 27  
 
 28  
 import org.apache.ojb.broker.Identity;
 29  
 import org.apache.ojb.broker.PersistenceBroker;
 30  
 import org.apache.ojb.broker.PersistenceBrokerException;
 31  
 import org.apache.ojb.broker.PersistenceBrokerSQLException;
 32  
 import org.apache.ojb.broker.core.ValueContainer;
 33  
 import org.apache.ojb.broker.metadata.ArgumentDescriptor;
 34  
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 35  
 import org.apache.ojb.broker.metadata.FieldDescriptor;
 36  
 import org.apache.ojb.broker.metadata.ProcedureDescriptor;
 37  
 import org.apache.ojb.broker.platforms.Platform;
 38  
 import org.apache.ojb.broker.platforms.PlatformException;
 39  
 import org.apache.ojb.broker.platforms.PlatformFactory;
 40  
 import org.apache.ojb.broker.query.BetweenCriteria;
 41  
 import org.apache.ojb.broker.query.Criteria;
 42  
 import org.apache.ojb.broker.query.ExistsCriteria;
 43  
 import org.apache.ojb.broker.query.FieldCriteria;
 44  
 import org.apache.ojb.broker.query.InCriteria;
 45  
 import org.apache.ojb.broker.query.NullCriteria;
 46  
 import org.apache.ojb.broker.query.Query;
 47  
 import org.apache.ojb.broker.query.SelectionCriteria;
 48  
 import org.apache.ojb.broker.query.SqlCriteria;
 49  
 import org.apache.ojb.broker.util.logging.Logger;
 50  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 51  
 
 52  
 /**
 53  
  * manages JDBC Connection and Statement resources.
 54  
  *
 55  
  * @author Thomas Mahler
 56  
  * @author <a href="mailto:rburt3@mchsi.com">Randall Burt</a>
 57  
  * @version $Id: StatementManager.java,v 1.1 2007-08-24 22:17:30 ewestfal Exp $
 58  
  */
 59  
 public class StatementManager implements StatementManagerIF
 60  
 {
 61  
     private Logger m_log = LoggerFactory.getLogger(StatementManager.class);
 62  
 
 63  
     /** the associated broker */
 64  
     private final PersistenceBroker m_broker;
 65  
     private Platform m_platform;
 66  
     /**
 67  
      * Used when OJB run in JBoss
 68  
      * TODO: Find a better solution to handle OJB within JBoss
 69  
      * --> the JCA implementation should solve this problem
 70  
      *
 71  
      * arminw:
 72  
      * Seems with JBoss 3.2.2 or higher the problem is gone, so we
 73  
      * can deprecate this attribute sooner or later
 74  
      */
 75  
     private boolean m_eagerRelease;
 76  
     private ConnectionManagerIF m_conMan;
 77  
 
 78  
     public StatementManager(final PersistenceBroker pBroker)
 79  
     {
 80  
         this.m_broker = pBroker;
 81  
         this.m_conMan = m_broker.serviceConnectionManager();
 82  
         m_eagerRelease = m_conMan.getConnectionDescriptor().getEagerRelease();
 83  
         m_platform = PlatformFactory.getPlatformFor(m_conMan.getConnectionDescriptor());
 84  
     }
 85  
 
 86  
     public void closeResources(Statement stmt, ResultSet rs)
 87  
     {
 88  
         if (m_log.isDebugEnabled())
 89  
             m_log.debug("closeResources was called");
 90  
         try
 91  
         {
 92  
             m_platform.beforeStatementClose(stmt, rs);
 93  
             //close statement on wrapped statement class, or real statement
 94  
             if (stmt != null)
 95  
             {
 96  
                 //log.info("## close: "+stmt);
 97  
                 stmt.close();
 98  
 
 99  
                 /*
 100  
                 *********************************************
 101  
                 special stuff for OJB within JBoss
 102  
                 ********************************************
 103  
                 */
 104  
                 if (m_eagerRelease)
 105  
                 {
 106  
                     m_conMan.releaseConnection();
 107  
                 }
 108  
 
 109  
             }
 110  
             m_platform.afterStatementClose(stmt, rs);
 111  
         }
 112  
         catch (PlatformException e)
 113  
         {
 114  
             m_log.error("Platform dependent operation failed", e);
 115  
         }
 116  
         catch (SQLException ignored)
 117  
         {
 118  
             if (m_log.isDebugEnabled())
 119  
                 m_log.debug("Statement closing failed", ignored);
 120  
         }
 121  
     }
 122  
 
 123  
     /**
 124  
      * binds the Identities Primary key values to the statement
 125  
      */
 126  
     public void bindDelete(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException
 127  
     {
 128  
         Object[] pkValues = oid.getPrimaryKeyValues();
 129  
         FieldDescriptor[] pkFields = cld.getPkFields();
 130  
         int i = 0;
 131  
         try
 132  
         {
 133  
             for (; i < pkValues.length; i++)
 134  
             {
 135  
                 setObjectForStatement(stmt, i + 1, pkValues[i], pkFields[i].getJdbcType().getType());
 136  
             }
 137  
         }
 138  
         catch (SQLException e)
 139  
         {
 140  
             m_log.error("bindDelete failed for: " + oid.toString() + ", while set value '" +
 141  
                     pkValues[i] + "' for column " + pkFields[i].getColumnName());
 142  
             throw e;
 143  
         }
 144  
     }
 145  
 
 146  
     /**
 147  
      * binds the objects primary key and locking values to the statement, BRJ
 148  
      */
 149  
     public void bindDelete(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws SQLException
 150  
     {
 151  
         if (cld.getDeleteProcedure() != null)
 152  
         {
 153  
             this.bindProcedure(stmt, cld, obj, cld.getDeleteProcedure());
 154  
         }
 155  
         else
 156  
         {
 157  
             int index = 1;
 158  
             ValueContainer[] values, currentLockingValues;
 159  
 
 160  
             currentLockingValues = cld.getCurrentLockingValues(obj);
 161  
             // parameters for WHERE-clause pk
 162  
             values = getKeyValues(m_broker, cld, obj);
 163  
             for (int i = 0; i < values.length; i++)
 164  
             {
 165  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 166  
                 index++;
 167  
             }
 168  
 
 169  
             // parameters for WHERE-clause locking
 170  
             values = currentLockingValues;
 171  
             for (int i = 0; i < values.length; i++)
 172  
             {
 173  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 174  
                 index++;
 175  
             }
 176  
         }
 177  
     }
 178  
 
 179  
     /**
 180  
      * bind attribute and value
 181  
      * @param stmt
 182  
      * @param index
 183  
      * @param attributeOrQuery
 184  
      * @param value
 185  
      * @param cld
 186  
      * @return
 187  
      * @throws SQLException
 188  
      */
 189  
     private int bindStatementValue(PreparedStatement stmt, int index, Object attributeOrQuery, Object value, ClassDescriptor cld)
 190  
             throws SQLException
 191  
     {
 192  
         FieldDescriptor fld = null;
 193  
         // if value is a subQuery bind it
 194  
         if (value instanceof Query)
 195  
         {
 196  
             Query subQuery = (Query) value;
 197  
             return bindStatement(stmt, subQuery, cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
 198  
         }
 199  
 
 200  
         // if attribute is a subQuery bind it
 201  
         if (attributeOrQuery instanceof Query)
 202  
         {
 203  
             Query subQuery = (Query) attributeOrQuery;
 204  
             bindStatement(stmt, subQuery, cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
 205  
         }
 206  
         else
 207  
         {
 208  
             fld = cld.getFieldDescriptorForPath((String) attributeOrQuery);
 209  
         }
 210  
 
 211  
         if (fld != null)
 212  
         {
 213  
             // BRJ: use field conversions and platform
 214  
             if (value != null)
 215  
             {
 216  
                 m_platform.setObjectForStatement(stmt, index, fld.getFieldConversion().javaToSql(value), fld.getJdbcType().getType());
 217  
             }
 218  
             else
 219  
             {
 220  
                 m_platform.setNullForStatement(stmt, index, fld.getJdbcType().getType());
 221  
             }
 222  
         }
 223  
         else
 224  
         {
 225  
             if (value != null)
 226  
             {
 227  
                 stmt.setObject(index, value);
 228  
             }
 229  
             else
 230  
             {
 231  
                 stmt.setNull(index, Types.NULL);
 232  
             }
 233  
         }
 234  
 
 235  
         return ++index; // increment before return
 236  
     }
 237  
 
 238  
     /**
 239  
      * bind SelectionCriteria
 240  
      * @param stmt the PreparedStatement
 241  
      * @param index the position of the parameter to bind
 242  
      * @param crit the Criteria containing the parameter
 243  
      * @param cld the ClassDescriptor
 244  
      * @return next index for PreparedStatement
 245  
      */
 246  
     private int bindStatement(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
 247  
     {
 248  
         return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
 249  
     }
 250  
 
 251  
     /**
 252  
      * bind NullCriteria
 253  
      * @param stmt the PreparedStatement
 254  
      * @param index the position of the parameter to bind
 255  
      * @param crit the Criteria containing the parameter
 256  
      * @return next index for PreparedStatement
 257  
      */
 258  
     private int bindStatement(PreparedStatement stmt, int index, NullCriteria crit)
 259  
     {
 260  
         return index;
 261  
     }
 262  
 
 263  
     /**
 264  
      * bind FieldCriteria
 265  
      * @param stmt , the PreparedStatement
 266  
      * @param index , the position of the parameter to bind
 267  
      * @param crit , the Criteria containing the parameter
 268  
      * @return next index for PreparedStatement
 269  
      */
 270  
     private int bindStatement(PreparedStatement stmt, int index, FieldCriteria crit)
 271  
     {
 272  
         return index;
 273  
     }
 274  
 
 275  
     /**
 276  
      * bind SqlCriteria
 277  
      * @param stmt the PreparedStatement
 278  
      * @param index the position of the parameter to bind
 279  
      * @param crit the Criteria containing the parameter
 280  
      * @return next index for PreparedStatement
 281  
      */
 282  
     private int bindStatement(PreparedStatement stmt, int index, SqlCriteria crit)
 283  
     {
 284  
         return index;
 285  
     }
 286  
 
 287  
     /**
 288  
      * bind BetweenCriteria
 289  
      * @param stmt the PreparedStatement
 290  
      * @param index the position of the parameter to bind
 291  
      * @param crit the Criteria containing the parameter
 292  
      * @param cld the ClassDescriptor
 293  
      * @return next index for PreparedStatement
 294  
      */
 295  
     private int bindStatement(PreparedStatement stmt, int index, BetweenCriteria crit, ClassDescriptor cld) throws SQLException
 296  
     {
 297  
         index = bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
 298  
 
 299  
         return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue2(), cld);
 300  
     }
 301  
 
 302  
     /**
 303  
      * bind InCriteria
 304  
      * @param stmt the PreparedStatement
 305  
      * @param index the position of the parameter to bind
 306  
      * @param crit the Criteria containing the parameter
 307  
      * @param cld the ClassDescriptor
 308  
      * @return next index for PreparedStatement
 309  
      */
 310  
     private int bindStatement(PreparedStatement stmt, int index, InCriteria crit, ClassDescriptor cld) throws SQLException
 311  
     {
 312  
         if (crit.getValue() instanceof Collection)
 313  
         {
 314  
             Collection values = (Collection) crit.getValue();
 315  
             Iterator iter = values.iterator();
 316  
 
 317  
             while (iter.hasNext())
 318  
             {
 319  
                 index = bindStatementValue(stmt, index, crit.getAttribute(), iter.next(), cld);
 320  
             }
 321  
         }
 322  
         else
 323  
         {
 324  
             index = bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
 325  
         }
 326  
         return index;
 327  
     }
 328  
 
 329  
     /**
 330  
      * bind ExistsCriteria
 331  
      * @param stmt the PreparedStatement
 332  
      * @param index the position of the parameter to bind
 333  
      * @param crit the Criteria containing the parameter
 334  
      * @param cld the ClassDescriptor
 335  
      * @return next index for PreparedStatement
 336  
      */
 337  
     private int bindStatement(PreparedStatement stmt, int index, ExistsCriteria crit, ClassDescriptor cld) throws SQLException
 338  
     {
 339  
         Query subQuery = (Query) crit.getValue();
 340  
 
 341  
         // if query has criteria, bind them
 342  
         if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
 343  
         {
 344  
             return bindStatement(stmt, subQuery.getCriteria(), cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
 345  
 
 346  
             // otherwise, just ignore it
 347  
         }
 348  
         else
 349  
         {
 350  
             return index;
 351  
         }
 352  
     }
 353  
 
 354  
     /**
 355  
      * bind a Query based Select Statement
 356  
      */
 357  
     public int bindStatement(PreparedStatement stmt, Query query, ClassDescriptor cld, int param) throws SQLException
 358  
     {
 359  
         int result;
 360  
 
 361  
         result = bindStatement(stmt, query.getCriteria(), cld, param);
 362  
         result = bindStatement(stmt, query.getHavingCriteria(), cld, result);
 363  
 
 364  
         return result;
 365  
     }
 366  
 
 367  
     /**
 368  
      * bind a Query based Select Statement
 369  
      */
 370  
     protected int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int param) throws SQLException
 371  
     {
 372  
         if (crit != null)
 373  
         {
 374  
             Enumeration e = crit.getElements();
 375  
 
 376  
             while (e.hasMoreElements())
 377  
             {
 378  
                 Object o = e.nextElement();
 379  
                 if (o instanceof Criteria)
 380  
                 {
 381  
                     Criteria pc = (Criteria) o;
 382  
                     param = bindStatement(stmt, pc, cld, param);
 383  
                 }
 384  
                 else
 385  
                 {
 386  
                     SelectionCriteria c = (SelectionCriteria) o;
 387  
                     // BRJ : bind once for the criterion's main class
 388  
                     param = bindSelectionCriteria(stmt, param, c, cld);
 389  
 
 390  
                     // BRJ : and once for each extent
 391  
                     for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
 392  
                     {
 393  
                         param = bindSelectionCriteria(stmt, param, c, cld);
 394  
                     }
 395  
                 }
 396  
             }
 397  
         }
 398  
         return param;
 399  
     }
 400  
 
 401  
     /**
 402  
      * bind SelectionCriteria
 403  
      * @param stmt the PreparedStatement
 404  
      * @param index the position of the parameter to bind
 405  
      * @param crit the Criteria containing the parameter
 406  
      * @param cld the ClassDescriptor
 407  
      * @return next index for PreparedStatement
 408  
      */
 409  
     private int bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
 410  
     {
 411  
         if (crit instanceof NullCriteria)
 412  
             index = bindStatement(stmt, index, (NullCriteria) crit);
 413  
         else if (crit instanceof BetweenCriteria)
 414  
             index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
 415  
         else if (crit instanceof InCriteria)
 416  
             index = bindStatement(stmt, index, (InCriteria) crit, cld);
 417  
         else if (crit instanceof SqlCriteria)
 418  
             index = bindStatement(stmt, index, (SqlCriteria) crit);
 419  
         else if (crit instanceof FieldCriteria)
 420  
             index = bindStatement(stmt, index, (FieldCriteria) crit);
 421  
         else if (crit instanceof ExistsCriteria)
 422  
             index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
 423  
         else
 424  
             index = bindStatement(stmt, index, crit, cld);
 425  
 
 426  
         return index;
 427  
     }
 428  
 
 429  
     /**
 430  
      * binds the values of the object obj to the statements parameters
 431  
      */
 432  
     public void bindInsert(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
 433  
     {
 434  
         ValueContainer[] values;
 435  
         cld.updateLockingValues(obj); // BRJ : provide useful defaults for locking fields
 436  
 
 437  
         if (cld.getInsertProcedure() != null)
 438  
         {
 439  
             this.bindProcedure(stmt, cld, obj, cld.getInsertProcedure());
 440  
         }
 441  
         else
 442  
         {
 443  
             values = getAllValues(cld, obj);
 444  
             for (int i = 0; i < values.length; i++)
 445  
             {
 446  
                 setObjectForStatement(stmt, i + 1, values[i].getValue(), values[i].getJdbcType().getType());
 447  
             }
 448  
         }
 449  
     }
 450  
 
 451  
     /**
 452  
      * Binds the Identities Primary key values to the statement.
 453  
      */
 454  
     public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld, boolean callableStmt) throws SQLException
 455  
     {
 456  
         ValueContainer[] values = null;
 457  
         int i = 0;
 458  
         int j = 0;
 459  
 
 460  
         if (cld == null)
 461  
         {
 462  
             cld = m_broker.getClassDescriptor(oid.getObjectsRealClass());
 463  
         }
 464  
         try
 465  
         {
 466  
             if(callableStmt)
 467  
             {
 468  
                 // First argument is the result set
 469  
                 m_platform.registerOutResultSet((CallableStatement) stmt, 1);
 470  
                 j++;
 471  
             }
 472  
 
 473  
             values = getKeyValues(m_broker, cld, oid);
 474  
             for (/*void*/; i < values.length; i++, j++)
 475  
             {
 476  
                 setObjectForStatement(stmt, j + 1, values[i].getValue(), values[i].getJdbcType().getType());
 477  
             }
 478  
         }
 479  
         catch (SQLException e)
 480  
         {
 481  
             m_log.error("bindSelect failed for: " + oid.toString() + ", PK: " + i + ", value: " + values[i]);
 482  
             throw e;
 483  
         }
 484  
     }
 485  
 
 486  
     /**
 487  
      * binds the values of the object obj to the statements parameters
 488  
      */
 489  
     public void bindUpdate(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
 490  
     {
 491  
         if (cld.getUpdateProcedure() != null)
 492  
         {
 493  
             this.bindProcedure(stmt, cld, obj, cld.getUpdateProcedure());
 494  
         }
 495  
         else
 496  
         {
 497  
             int index = 1;
 498  
             ValueContainer[] values, valuesSnapshot;
 499  
             // first take a snapshot of current locking values
 500  
             valuesSnapshot = cld.getCurrentLockingValues(obj);
 501  
             cld.updateLockingValues(obj); // BRJ
 502  
             values = getNonKeyValues(m_broker, cld, obj);
 503  
 
 504  
             // parameters for SET-clause
 505  
             for (int i = 0; i < values.length; i++)
 506  
             {
 507  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 508  
                 index++;
 509  
             }
 510  
             // parameters for WHERE-clause pk
 511  
             values = getKeyValues(m_broker, cld, obj);
 512  
             for (int i = 0; i < values.length; i++)
 513  
             {
 514  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 515  
                 index++;
 516  
             }
 517  
             // parameters for WHERE-clause locking
 518  
             // take old locking values
 519  
             values = valuesSnapshot;
 520  
             for (int i = 0; i < values.length; i++)
 521  
             {
 522  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 523  
                 index++;
 524  
             }
 525  
         }
 526  
     }
 527  
 
 528  
     /**
 529  
      * binds the given array of values (if not null) starting from the given
 530  
      * parameter index
 531  
      * @return the next parameter index
 532  
      */
 533  
     public int bindValues(PreparedStatement stmt, ValueContainer[] values, int index) throws SQLException
 534  
     {
 535  
         if (values != null)
 536  
         {
 537  
             for (int i = 0; i < values.length; i++)
 538  
             {
 539  
                 setObjectForStatement(stmt, index, values[i].getValue(), values[i].getJdbcType().getType());
 540  
                 index++;
 541  
             }
 542  
         }
 543  
         return index;
 544  
     }
 545  
 
 546  
     /**
 547  
      * return a prepared DELETE Statement fitting for the given ClassDescriptor
 548  
      */
 549  
     public PreparedStatement getDeleteStatement(ClassDescriptor cld) throws PersistenceBrokerSQLException, PersistenceBrokerException
 550  
     {
 551  
         try
 552  
         {
 553  
             return cld.getStatementsForClass(m_conMan).getDeleteStmt(m_conMan.getConnection());
 554  
         }
 555  
         catch (SQLException e)
 556  
         {
 557  
             throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
 558  
         }
 559  
         catch (LookupException e)
 560  
         {
 561  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 562  
         }
 563  
     }
 564  
 
 565  
     /**
 566  
      * return a generic Statement for the given ClassDescriptor.
 567  
      * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
 568  
      */
 569  
     public Statement getGenericStatement(ClassDescriptor cds, boolean scrollable) throws PersistenceBrokerException
 570  
     {
 571  
         try
 572  
         {
 573  
             return cds.getStatementsForClass(m_conMan).getGenericStmt(m_conMan.getConnection(), scrollable);
 574  
         }
 575  
         catch (LookupException e)
 576  
         {
 577  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 578  
         }
 579  
     }
 580  
 
 581  
     /**
 582  
      * return a prepared Insert Statement fitting for the given ClassDescriptor
 583  
      */
 584  
     public PreparedStatement getInsertStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
 585  
     {
 586  
         try
 587  
         {
 588  
             return cds.getStatementsForClass(m_conMan).getInsertStmt(m_conMan.getConnection());
 589  
         }
 590  
         catch (SQLException e)
 591  
         {
 592  
             throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
 593  
         }
 594  
         catch (LookupException e)
 595  
         {
 596  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 597  
         }
 598  
     }
 599  
 
 600  
     /**
 601  
      * return a generic Statement for the given ClassDescriptor
 602  
      */
 603  
     public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql,
 604  
                                                   boolean scrollable, int explicitFetchSizeHint, boolean callableStmt)
 605  
             throws PersistenceBrokerException
 606  
     {
 607  
         try
 608  
         {
 609  
             return cds.getStatementsForClass(m_conMan).getPreparedStmt(m_conMan.getConnection(), sql, scrollable, explicitFetchSizeHint, callableStmt);
 610  
         }
 611  
         catch (LookupException e)
 612  
         {
 613  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 614  
         }
 615  
     }
 616  
 
 617  
     /**
 618  
      * return a prepared Select Statement for the given ClassDescriptor
 619  
      */
 620  
     public PreparedStatement getSelectByPKStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
 621  
     {
 622  
         try
 623  
         {
 624  
             return cds.getStatementsForClass(m_conMan).getSelectByPKStmt(m_conMan.getConnection());
 625  
         }
 626  
         catch (SQLException e)
 627  
         {
 628  
             throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
 629  
         }
 630  
         catch (LookupException e)
 631  
         {
 632  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 633  
         }
 634  
     }
 635  
 
 636  
     /**
 637  
      * return a prepared Update Statement fitting to the given ClassDescriptor
 638  
      */
 639  
     public PreparedStatement getUpdateStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
 640  
     {
 641  
         try
 642  
         {
 643  
             return cds.getStatementsForClass(m_conMan).getUpdateStmt(m_conMan.getConnection());
 644  
         }
 645  
         catch (SQLException e)
 646  
         {
 647  
             throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
 648  
         }
 649  
         catch (LookupException e)
 650  
         {
 651  
             throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
 652  
         }
 653  
     }
 654  
 
 655  
     /**
 656  
      * returns an array containing values for all the Objects attribute
 657  
      * @throws PersistenceBrokerException if there is an erros accessing obj field values
 658  
      */
 659  
     protected ValueContainer[] getAllValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
 660  
     {
 661  
         return m_broker.serviceBrokerHelper().getAllRwValues(cld, obj);
 662  
     }
 663  
 
 664  
     /**
 665  
      * returns an Array with an Objects PK VALUES
 666  
      * @throws PersistenceBrokerException if there is an erros accessing o field values
 667  
      */
 668  
     protected ValueContainer[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
 669  
     {
 670  
         return broker.serviceBrokerHelper().getKeyValues(cld, obj);
 671  
     }
 672  
 
 673  
     /**
 674  
      * returns an Array with an Identities PK VALUES
 675  
      * @throws PersistenceBrokerException if there is an erros accessing o field values
 676  
      */
 677  
     protected ValueContainer[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Identity oid) throws PersistenceBrokerException
 678  
     {
 679  
         return broker.serviceBrokerHelper().getKeyValues(cld, oid);
 680  
     }
 681  
 
 682  
     /**
 683  
      * returns an Array with an Objects NON-PK VALUES
 684  
      * @throws PersistenceBrokerException if there is an erros accessing o field values
 685  
      */
 686  
     protected ValueContainer[] getNonKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
 687  
     {
 688  
         return broker.serviceBrokerHelper().getNonKeyRwValues(cld, obj);
 689  
     }
 690  
 
 691  
     /**
 692  
      * Bind a prepared statment that represents a call to a procedure or
 693  
      * user-defined function.
 694  
      *
 695  
      * @param stmt the statement to bind.
 696  
      * @param cld the class descriptor of the object that triggered the
 697  
      *        invocation of the procedure or user-defined function.
 698  
      * @param obj the object that triggered the invocation of the procedure
 699  
      *        or user-defined function.
 700  
      * @param proc the procedure descriptor that provides information about
 701  
      *        the arguments that shoudl be passed to the procedure or
 702  
      *        user-defined function
 703  
      */
 704  
     private void bindProcedure(PreparedStatement stmt, ClassDescriptor cld, Object obj, ProcedureDescriptor proc)
 705  
             throws SQLException
 706  
     {
 707  
         int valueSub = 0;
 708  
 
 709  
         // Figure out if we are using a callable statement.  If we are, then we
 710  
         // will need to register one or more output parameters.
 711  
         CallableStatement callable = null;
 712  
         try
 713  
         {
 714  
             callable = (CallableStatement) stmt;
 715  
         }
 716  
         catch(Exception e)
 717  
         {
 718  
             m_log.error("Error while bind values for class '" + (cld != null ? cld.getClassNameOfObject() : null)
 719  
                     + "', using stored procedure: "+ proc, e);
 720  
             if(e instanceof SQLException)
 721  
             {
 722  
                 throw (SQLException) e;
 723  
             }
 724  
             else
 725  
             {
 726  
                 throw new PersistenceBrokerException("Unexpected error while bind values for class '"
 727  
                         + (cld != null ? cld.getClassNameOfObject() : null) + "', using stored procedure: "+ proc);
 728  
             }
 729  
         }
 730  
 
 731  
         // If we have a return value, then register it.
 732  
         if ((proc.hasReturnValue()) && (callable != null))
 733  
         {
 734  
             int jdbcType = proc.getReturnValueFieldRef().getJdbcType().getType();
 735  
             m_platform.setNullForStatement(stmt, valueSub + 1, jdbcType);
 736  
             callable.registerOutParameter(valueSub + 1, jdbcType);
 737  
             valueSub++;
 738  
         }
 739  
 
 740  
         // Process all of the arguments.
 741  
         Iterator iterator = proc.getArguments().iterator();
 742  
         while (iterator.hasNext())
 743  
         {
 744  
             ArgumentDescriptor arg = (ArgumentDescriptor) iterator.next();
 745  
             Object val = arg.getValue(obj);
 746  
             int jdbcType = arg.getJdbcType();
 747  
             setObjectForStatement(stmt, valueSub + 1, val, jdbcType);
 748  
             if ((arg.getIsReturnedByProcedure()) && (callable != null))
 749  
             {
 750  
                 callable.registerOutParameter(valueSub + 1, jdbcType);
 751  
             }
 752  
             valueSub++;
 753  
         }
 754  
     }
 755  
 
 756  
     /**
 757  
      * Sets object for statement at specific index, adhering to platform- and null-rules.
 758  
      * @param stmt the statement
 759  
      * @param index the current parameter index
 760  
      * @param value the value to set
 761  
      * @param sqlType the JDBC SQL-type of the value
 762  
      * @throws SQLException on platform error
 763  
      */
 764  
     private void setObjectForStatement(PreparedStatement stmt, int index, Object value, int sqlType)
 765  
             throws SQLException
 766  
     {
 767  
         if (value == null)
 768  
         {
 769  
             m_platform.setNullForStatement(stmt, index, sqlType);
 770  
         }
 771  
         else
 772  
         {
 773  
             m_platform.setObjectForStatement(stmt, index, value, sqlType);
 774  
         }
 775  
     }
 776  
 
 777  
 }