java.lang.Object
org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor
All Implemented Interfaces:
Cloneable, Accessor

public class DatabaseAccessor extends DatasourceAccessor
INTERNAL: DatabaseAccessor is private to EclipseLink. It encapsulates low level database operations (such as executing SQL and reading data by row). Database accessor defines a protocol by which EclipseLink may invoke these operations.

DatabaseAccessor also defines a single reference through which all configuration dependent behavior may be invoked.

DabaseAccessor implements the following behavior.

  • Connect and disconnect from the database.
  • Execute SQL statements on the database, returning results.
  • Handle auto-commit and transactions.
DatabaseAccessor dispatches the following protocols to its platform reference.
  • Provision of database platform specific type names.
DatabaseAccessor dispatches the following protocols to the schema object.
  • Creation and deletion of schema objects.
Since:
TOPLink/Java 1.0
See Also:
  • Field Details

    • shouldUseDynamicStatements

      public static boolean shouldUseDynamicStatements
      PERF: Backdoor to disabling dynamic statements. Reverts to old prepared statement usage if set.
    • statementCache

      protected Map<String,Statement> statementCache
      Stores statement handles for common used prepared statements.
    • metaData

      protected DatabaseMetaData metaData
      Cache of the connection's java.sql.DatabaseMetaData
    • activeBatchWritingMechanism

      protected BatchWritingMechanism activeBatchWritingMechanism
      This attribute will be used to store the currently active Batch Mechanism
    • dynamicSQLMechanism

      protected DynamicSQLBatchWritingMechanism dynamicSQLMechanism
      These two attributes store the available BatchWritingMechanisms. We sacrifice a little space to prevent the work involved in recreating these objects each time a different type of SQL statement is executed. Depending on user behavior we may want to review this.
    • parameterizedMechanism

      protected ParameterizedSQLBatchWritingMechanism parameterizedMechanism
    • lobWriter

      protected LOBValueWriter lobWriter
    • dynamicStatement

      protected Statement dynamicStatement
      PERF: Cache the statement object for dynamic SQL execution.
    • isDynamicStatementInUse

      protected boolean isDynamicStatementInUse
  • Constructor Details

    • DatabaseAccessor

      public DatabaseAccessor()
    • DatabaseAccessor

      public DatabaseAccessor(Object connection)
      Create a database accessor with the given connection.
  • Method Details

    • getDynamicSQLMechanism

      protected DynamicSQLBatchWritingMechanism getDynamicSQLMechanism()
      Lazy init the dynamic SQL mechanism.
    • getParameterizedMechanism

      protected ParameterizedSQLBatchWritingMechanism getParameterizedMechanism()
      Lazy init the parameterized SQL mechanism.
    • flushSelectCalls

      public void flushSelectCalls(AbstractSession session)
      Execute any deferred select calls stored in the LOBValueWriter instance. This method will typically be called by the CallQueryMechanism object. Bug 2804663.
      Specified by:
      flushSelectCalls in interface Accessor
      Overrides:
      flushSelectCalls in class DatasourceAccessor
      See Also:
    • getLOBWriter

      public LOBValueWriter getLOBWriter()
      Return the LOBValueWriter instance. Lazily initialize the instance. Bug 2804663.
      See Also:
    • allocateDynamicStatement

      public Statement allocateDynamicStatement(Connection connection) throws SQLException
      Allocate a statement for dynamic SQL execution. Either return the cached dynamic statement, or a new statement. This statement must be released after execution.
      Throws:
      SQLException
    • isDynamicStatementInUse

      public boolean isDynamicStatementInUse()
      Return the cached statement for dynamic SQL execution is in use. Used to handle concurrency for the dynamic statement, this method must only be called from within a synchronized method/block.
    • setDatasourcePlatform

      public void setDatasourcePlatform(DatasourcePlatform platform)
      Set the platform. This should be set to the session's platform, not the connections which may not be configured correctly.
      Overrides:
      setDatasourcePlatform in class DatasourceAccessor
    • setIsDynamicStatementInUse

      public void setIsDynamicStatementInUse(boolean isDynamicStatementInUse)
      Set if the cached statement for dynamic SQL execution is in use. Used to handle concurrency for the dynamic statement.
    • basicBeginTransaction

      public void basicBeginTransaction(AbstractSession session) throws DatabaseException
      Begin a transaction on the database. This means toggling the auto-commit option.
      Specified by:
      basicBeginTransaction in class DatasourceAccessor
      Throws:
      DatabaseException
    • buildConnectLog

      protected void buildConnectLog(AbstractSession session)
      If logging is turned on and the JDBC implementation supports meta data then display connection info.
      Specified by:
      buildConnectLog in class DatasourceAccessor
    • buildOutputRow

      public AbstractRecord buildOutputRow(CallableStatement statement, DatabaseCall call, AbstractSession session) throws DatabaseException
      Build a row from the output parameters of a sp call.
      Throws:
      DatabaseException
    • buildSortedFields

      public Vector<DatabaseField> buildSortedFields(Vector<DatabaseField> fields, ResultSet resultSet, AbstractSession session) throws DatabaseException
      Return the field sorted in the correct order corresponding to the result set. This is used for cursored selects where custom sql was provided. If the fields passed in are null, this means that the field are not known and should be built from the column names. This case occurs for DataReadQuery's.
      Throws:
      DatabaseException
    • connectInternal

      protected void connectInternal(Login login, AbstractSession session) throws DatabaseException
      Connect to the database. Exceptions are caught and re-thrown as EclipseLink exceptions. Must set the transaction isolation.
      Overrides:
      connectInternal in class DatasourceAccessor
      Throws:
      DatabaseException
    • checkTransactionIsolation

      protected void checkTransactionIsolation(AbstractSession session) throws DatabaseException
      Check to see if the transaction isolation needs to be set for the newly created connection. This must be done outside of a transaction. Exceptions are caught and re-thrown as EclipseLink exceptions.
      Throws:
      DatabaseException
    • clearStatementCache

      public void clearStatementCache(AbstractSession session)
      Flush the statement cache. Each statement must first be closed.
    • clone

      public Object clone()
      Clone the accessor.
      Specified by:
      clone in interface Accessor
      Overrides:
      clone in class DatasourceAccessor
    • closeCursor

      public void closeCursor(ResultSet resultSet, AbstractSession session) throws DatabaseException
      Close the result set of the cursored stream.
      Throws:
      DatabaseException
    • closeStatement

      public void closeStatement(Statement statement, AbstractSession session, DatabaseCall call) throws SQLException
      INTERNAL: Closes a PreparedStatement (which is supposed to close it's current resultSet). Factored out to simplify coding and handle exceptions.
      Throws:
      SQLException
    • commitTransaction

      public void commitTransaction(AbstractSession session) throws DatabaseException
      Commit a transaction on the database. First flush any batched statements.
      Specified by:
      commitTransaction in interface Accessor
      Overrides:
      commitTransaction in class DatasourceAccessor
      Throws:
      DatabaseException
    • basicCommitTransaction

      public void basicCommitTransaction(AbstractSession session) throws DatabaseException
      Commit a transaction on the database. This means toggling the auto-commit option.
      Specified by:
      basicCommitTransaction in class DatasourceAccessor
      Throws:
      DatabaseException
    • cursorRetrieveNextRow

      public AbstractRecord cursorRetrieveNextRow(Vector<DatabaseField> fields, ResultSet resultSet, AbstractSession session) throws DatabaseException
      Advance the result set and return a Record populated with values from the next valid row in the result set. Intended solely for cursored stream support.
      Throws:
      DatabaseException
    • cursorRetrievePreviousRow

      public AbstractRecord cursorRetrievePreviousRow(Vector<DatabaseField> fields, ResultSet resultSet, AbstractSession session) throws DatabaseException
      Advance the result set and return a DatabaseRow populated with values from the next valid row in the result set. Intended solely for scrollable cursor support.
      Throws:
      DatabaseException
    • closeDatasourceConnection

      public void closeDatasourceConnection() throws DatabaseException
      Close the connection.
      Specified by:
      closeDatasourceConnection in class DatasourceAccessor
      Throws:
      DatabaseException
    • disconnect

      public void disconnect(AbstractSession session) throws DatabaseException
      Disconnect from the datasource. Added for bug 3046465 to ensure the statement cache is cleared.
      Specified by:
      disconnect in interface Accessor
      Overrides:
      disconnect in class DatasourceAccessor
      Throws:
      DatabaseException
    • closeConnection

      public void closeConnection()
      Close the accessor's connection. This is used only for external connection pooling when it is intended for the connection to be reconnected in the future.
      Specified by:
      closeConnection in interface Accessor
      Overrides:
      closeConnection in class DatasourceAccessor
    • executeBatchedStatement

      protected void executeBatchedStatement(PreparedStatement statement, AbstractSession session) throws DatabaseException
      Execute the EclipseLink dynamically batched/concatenated statement.
      Throws:
      DatabaseException
    • executeCall

      public Object executeCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException
      Execute the call. The execution can differ slightly depending on the type of call. The call may be parameterized where the arguments are in the translation row. The row will be empty if there are no parameters.
      Specified by:
      executeCall in interface Accessor
      Overrides:
      executeCall in class DatasourceAccessor
      Returns:
      depending of the type either the row count, row or vector of rows.
      Throws:
      DatabaseException
    • basicExecuteCall

      public Object basicExecuteCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException
      Execute the call. The execution can differ slightly depending on the type of call. The call may be parameterized where the arguments are in the translation row. The row will be empty if there are no parameters.
      Specified by:
      basicExecuteCall in class DatasourceAccessor
      Returns:
      depending of the type either the row count, row or vector of rows.
      Throws:
      DatabaseException
    • basicExecuteCall

      public Object basicExecuteCall(Call call, AbstractRecord translationRow, AbstractSession session, boolean batch) throws DatabaseException
      Execute the call. The execution can differ slightly depending on the type of call. The call may be parameterized where the arguments are in the translation row. The row will be empty if there are no parameters.
      Returns:
      depending of the type either the row count, row or vector of rows.
      Throws:
      DatabaseException
    • processResultSet

      public Object processResultSet(ResultSet resultSet, DatabaseCall call, Statement statement, AbstractSession session) throws SQLException
      Fetch all the rows from the result set.
      Throws:
      SQLException
    • buildThreadCursoredResult

      protected Vector<AbstractRecord> buildThreadCursoredResult(DatabaseCall dbCall, ResultSet resultSet, Statement statement, ResultSetMetaData metaData, AbstractSession session)
      This allows for the rows to be fetched concurrently to the objects being built. This code is not currently publicly supported.
    • executeDirectNoSelect

      public Object executeDirectNoSelect(Statement statement, DatabaseCall call, AbstractSession session) throws DatabaseException
      Execute the statement.
      Throws:
      DatabaseException
    • executeJDK12BatchStatement

      protected int executeJDK12BatchStatement(Statement statement, DatabaseCall dbCall, AbstractSession session, boolean isStatementPrepared) throws DatabaseException
      Execute the batched statement through the JDBC2 API.
      Throws:
      DatabaseException
    • executeNoSelect

      protected Object executeNoSelect(DatabaseCall call, Statement statement, AbstractSession session) throws DatabaseException
      Execute the statement.
      Throws:
      DatabaseException
    • execute

      public boolean execute(DatabaseCall call, Statement statement, AbstractSession session) throws SQLException
      Execute the statement.
      Throws:
      SQLException
    • executeSelect

      public ResultSet executeSelect(DatabaseCall call, Statement statement, AbstractSession session) throws SQLException
      Execute the statement.
      Throws:
      SQLException
    • fetchRow

      protected AbstractRecord fetchRow(Vector<DatabaseField> fields, ResultSet resultSet, ResultSetMetaData metaData, AbstractSession session) throws DatabaseException
      Return a new DatabaseRow.

      Populate the row from the data in cursor. The fields representing the results and the order of the results are stored in fields.

      NOTE: Make sure that the field name is set. An empty field name placeholder is used in the sortFields() method when the number of fields defined does not match the number of column names available on the database. PERF: This method must be highly optimized.

      Throws:
      DatabaseException
    • fetchRow

      public AbstractRecord fetchRow(Vector<DatabaseField> fields, DatabaseField[] fieldsArray, ResultSet resultSet, ResultSetMetaData metaData, AbstractSession session) throws DatabaseException
      Return a new DatabaseRow.

      Populate the row from the data in cursor. The fields representing the results and the order of the results are stored in fields.

      NOTE: Make sure that the field name is set. An empty field name placeholder is used in the sortFields() method when the number of fields defined does not match the number of column names available on the database. PERF: This method must be highly optimized.

      Throws:
      DatabaseException
    • populateRow

      public void populateRow(DatabaseField[] fieldsArray, Object[] values, ResultSet resultSet, ResultSetMetaData metaData, AbstractSession session, int startIndex, int endIndex) throws DatabaseException
      Throws:
      DatabaseException
    • getActiveBatchWritingMechanism

      public BatchWritingMechanism getActiveBatchWritingMechanism(AbstractSession session)
      INTERNAL: This method is used internally to return the active batch writing mechanism to batch the statement
    • getColumnInfo

      public Vector<AbstractRecord> getColumnInfo(String catalog, String schema, String tableName, String columnName, AbstractSession session) throws DatabaseException
      Get a description of table columns available in a catalog.

      Only column descriptions matching the catalog, schema, table and column name criteria are returned. They are ordered by TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.

      Each column description has the following columns:

      1. TABLE_CAT String => table catalog (may be null)
      2. TABLE_SCHEM String => table schema (may be null)
      3. TABLE_NAME String => table name
      4. COLUMN_NAME String => column name
      5. DATA_TYPE short => SQL type from java.sql.Types
      6. TYPE_NAME String => Data source dependent type name
      7. COLUMN_SIZE int => column size. For char or date types this is the maximum number of characters, for numeric or decimal types this is precision.
      8. BUFFER_LENGTH is not used.
      9. DECIMAL_DIGITS int => the number of fractional digits
      10. NUM_PREC_RADIX int => Radix (typically either 10 or 2)
      11. NULLABLE int => is NULL allowed?
        • columnNoNulls - might not allow NULL values
        • columnNullable - definitely allows NULL values
        • columnNullableUnknown - nullability unknown
      12. REMARKS String => comment describing column (may be null)
      13. COLUMN_DEF String => default value (may be null)
      14. SQL_DATA_TYPE int => unused
      15. SQL_DATETIME_SUB int => unused
      16. CHAR_OCTET_LENGTH int => for char types the maximum number of bytes in the column
      17. ORDINAL_POSITION int => index of column in table (starting at 1)
      18. IS_NULLABLE String => "NO" means column definitely does not allow NULL values; "YES" means the column might allow NULL values. An empty string means nobody knows.
      Specified by:
      getColumnInfo in interface Accessor
      Overrides:
      getColumnInfo in class DatasourceAccessor
      Parameters:
      catalog - a catalog name; "" retrieves those without a catalog; null means drop catalog name from the selection criteria
      schema - schema name pattern; "" retrieves those without a schema
      tableName - a table name pattern
      columnName - a column name pattern
      Returns:
      a Vector of DatabaseRows.
      Throws:
      DatabaseException
    • getColumnInfo

      public Vector<AbstractRecord> getColumnInfo(String tableName, String columnName, AbstractSession session) throws DatabaseException
      Description copied from interface: Accessor
      Return the column metadata for the specified selection criteria limited to the context of the current Accessor.
      Specified by:
      getColumnInfo in interface Accessor
      Overrides:
      getColumnInfo in class DatasourceAccessor
      Throws:
      DatabaseException
    • getSchema

      public String getSchema() throws SQLException
      Get the current schema. The accessor has to be connected.
      Returns:
      current schema name
      Throws:
      SQLException
    • getCatalog

      public String getCatalog() throws SQLException
      Get the current schema. The accessor has to be connected.
      Returns:
      current calatog name
      Throws:
      SQLException
    • getColumnNames

      protected Vector<DatabaseField> getColumnNames(ResultSet resultSet, AbstractSession session) throws SQLException
      Return the column names from a result sets meta data as a vector of DatabaseFields. This is required for custom SQL execution only, as generated SQL already knows the fields returned.
      Throws:
      SQLException
    • getConnection

      public Connection getConnection() throws DatabaseException
      Return the receiver's connection to its data source. A connection is used to execute queries on, and retrieve data from, a data source.
      Specified by:
      getConnection in interface Accessor
      Overrides:
      getConnection in class DatasourceAccessor
      Throws:
      DatabaseException
      See Also:
    • getPlatform

      public DatabasePlatform getPlatform()
      Return the platform.
    • getConnectionMetaData

      public DatabaseMetaData getConnectionMetaData() throws SQLException
      return the cached metaData
      Throws:
      SQLException
    • getObject

      public Object getObject(ResultSet resultSet, DatabaseField field, ResultSetMetaData metaData, int columnNumber, DatabasePlatform platform, boolean optimizeData, AbstractSession session) throws DatabaseException
      Return an object retrieved from resultSet with the getObject() method. Optimize the get for certain type to avoid double conversion. NOTE: This method handles a virtual machine error thrown when retrieving times & dates from Oracle or Sybase.
      Throws:
      DatabaseException
    • getObjectThroughOptimizedDataConversion

      protected Object getObjectThroughOptimizedDataConversion(ResultSet resultSet, DatabaseField field, int type, int columnNumber, DatabasePlatform platform, AbstractSession session) throws SQLException
      Handle the ResultSet conversion into java optimally through calling the direct type API.
      Parameters:
      resultSet - JDBC ResultSet with query result
      field - database field mapping
      type - database type from Types or provider specific type
      columnNumber - number of column to fetch
      platform - current database platform
      session - current database session
      Returns:
      new instance of converted type or this if no optimized conversion wasdone
      Throws:
      SQLException
    • hasStatementCache

      protected boolean hasStatementCache()
      Return if the accessor has any cached statements. This should be used to avoid lazy instantiation of the cache.
    • getStatementCache

      protected Map<String,Statement> getStatementCache()
      The statement cache stores a fixed sized number of prepared statements.
    • getTableInfo

      public Vector<AbstractRecord> getTableInfo(String catalog, String schema, String tableName, String[] types, AbstractSession session) throws DatabaseException
      Get a description of tables available in a catalog.

      Only table descriptions matching the catalog, schema, table name and type criteria are returned. They are ordered by TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.

      Each table description has the following columns:

      1. TABLE_CAT String => table catalog (may be null)
      2. TABLE_SCHEM String => table schema (may be null)
      3. TABLE_NAME String => table name
      4. TABLE_TYPE String => table type. Typical types are "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
      5. REMARKS String => explanatory comment on the table

      Note: Some databases may not return information for all tables.

      Specified by:
      getTableInfo in interface Accessor
      Overrides:
      getTableInfo in class DatasourceAccessor
      Parameters:
      catalog - a catalog name; "" retrieves those without a catalog; null means drop catalog name from the selection criteria
      schema - a schema name pattern; "" retrieves those without a schema
      tableName - a table name pattern
      types - a list of table types to include; null returns all types
      Returns:
      a Vector of DatabaseRows.
      Throws:
      DatabaseException
    • getTableInfo

      public Vector<AbstractRecord> getTableInfo(String tableName, String[] types, AbstractSession session) throws DatabaseException
      Description copied from interface: Accessor
      Return the table metadata for the specified selection criteria limited to the context of the current Accessor.
      Specified by:
      getTableInfo in interface Accessor
      Overrides:
      getTableInfo in class DatasourceAccessor
      Throws:
      DatabaseException
    • isDatasourceConnected

      public boolean isDatasourceConnected()
      Return true if the receiver is currently connected to a data source. Return false otherwise.
      Specified by:
      isDatasourceConnected in class DatasourceAccessor
    • isInBatchWritingMode

      protected boolean isInBatchWritingMode(AbstractSession session)
      Return the batch writing mode.
    • prepareStatement

      public Statement prepareStatement(DatabaseCall call, AbstractSession session) throws SQLException
      Prepare the SQL statement for the call. First check if the statement is cached before building a new one. Currently the SQL string is used as the cache key, this may have to be switched if it becomes a performance problem.
      Throws:
      SQLException
    • prepareStatement

      public Statement prepareStatement(DatabaseCall call, AbstractSession session, boolean unwrapConnection) throws SQLException
      Prepare the SQL statement for the call. First check if the statement is cached before building a new one.
      Parameters:
      unwrapConnection - boolean flag set to true to unwrap the connection before preparing the statement in the case of a parameterized call.
      Throws:
      SQLException
    • prepareStatement

      public PreparedStatement prepareStatement(String sql, AbstractSession session, boolean callable) throws SQLException
      Prepare the SQL statement for the call. First check if the statement is cached before building a new one.
      Throws:
      SQLException
    • processExceptionForCommError

      public DatabaseException processExceptionForCommError(AbstractSession session, SQLException exception, Call call)
      This method is used to process an SQL exception and determine if the exception should be passed on for further processing. If the Exception was communication based then a DatabaseException will be return. If the method did not process the message of it was not a comm failure then null will be returned.
    • reconnect

      protected void reconnect(AbstractSession session)
      Attempt to save some of the cost associated with getting a fresh connection. Assume the DatabaseDriver has been cached, if appropriate. Note: Connections that are participating in transactions will not be refreshed.^M Added for bug 3046465 to ensure the statement cache is cleared
      Overrides:
      reconnect in class DatasourceAccessor
    • releaseStatement

      public void releaseStatement(Statement statement, String sqlString, DatabaseCall call, AbstractSession session) throws SQLException
      Release the statement through closing it or putting it back in the statement cache.
      Throws:
      SQLException
    • resetStatementFromCall

      protected void resetStatementFromCall(Statement statement, DatabaseCall call) throws SQLException
      Reset the Query Timeout, Max Rows, Resultset fetch size on the Statement if the DatabaseCall has values which differ from the default settings. For Bug 5709179 - reset settings on cached statements
      Throws:
      SQLException
    • rollbackTransaction

      public void rollbackTransaction(AbstractSession session) throws DatabaseException
      Rollback a transaction on the database. This means toggling the auto-commit option.
      Specified by:
      rollbackTransaction in interface Accessor
      Overrides:
      rollbackTransaction in class DatasourceAccessor
      Throws:
      DatabaseException
    • basicRollbackTransaction

      public void basicRollbackTransaction(AbstractSession session) throws DatabaseException
      Rollback a transaction on the database. This means toggling the auto-commit option.
      Specified by:
      basicRollbackTransaction in class DatasourceAccessor
      Throws:
      DatabaseException
    • setActiveBatchWritingMechanismToParameterizedSQL

      public void setActiveBatchWritingMechanismToParameterizedSQL()
      INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
    • setActiveBatchWritingMechanismToDynamicSQL

      public void setActiveBatchWritingMechanismToDynamicSQL()
      INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
    • setActiveBatchWritingMechanism

      public void setActiveBatchWritingMechanism(BatchWritingMechanism mechanism)
      INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
    • setStatementCache

      protected void setStatementCache(Hashtable<String,Statement> statementCache)
      The statement cache stores a fixed sized number of prepared statements.
    • sortFields

      protected Vector<DatabaseField> sortFields(Vector<DatabaseField> fields, Vector<DatabaseField> columnNames)
      This method will sort the fields in correct order based on the column names.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • isBlob

      public static boolean isBlob(int type)
      Return if the JDBC type is a binary type such as blob.
    • isClob

      public static boolean isClob(int type)
      Return if the JDBC type is a large character type such as clob.
    • writesCompleted

      public void writesCompleted(AbstractSession session)
      This method will be called after a series of writes have been issued to mark where a particular set of writes has completed. It will be called from commitTransaction and may be called from writeChanges. Its main purpose is to ensure that the batched statements have been executed
      Specified by:
      writesCompleted in interface Accessor
      Overrides:
      writesCompleted in class DatasourceAccessor