Showing posts with label datasource. Show all posts
Showing posts with label datasource. Show all posts

Friday, February 12, 2010

IBM: DB Tools dbbeans.jar

DBBeans.jar

IBM DBBeans.jar comes with elegant APIs for JDBC and simplifies JDBC. Approx +/- 25 JAVA files implemented to do this. This jar is shipped as part of WSAD/RAD in datatools plugin. This jar is DB acqnostic and ready to use directly in application

In JDBC implementation, we have to establish DB connection and then create statement from connection. However, in this jar, we can tag a connection in a statement bean object.

DBStatement is the super class which helps to define statements. DBStatement offers API to release the resource in various levels by calling close(...) API. DBStatement comes with three different flavours

DBSelect
created and used to select rows from DB, which gives facility to retrieve number of rows fetched.
DBModify
makes insert or update or delete operation in DB
DBProcedureCall
calls stored procedure in DB. This class is subclass of DBSelect

DBSelectBeanInfo, DBModifyBeanInfo, DBProcedureCallBeanInfo are the beans stores information for the above listed statements.

DB Events

This implementation facilitate to triggers events before/after calling/executing the DBStatement. We can achive this by registering listener(DBBeforeListener/DBAfterListener) implemented classes in DBStatement.


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.ibm.db.beans.DBModify;
import com.ibm.db.beans.DBProcedureCall;
import com.ibm.db.beans.DBSelect;
import com.ibm.db.beans.DBStatement;

public class DBStatementFactory {

 public static DBSelect getDBSelect() {
  DBSelect dbSelect = new DBSelect();
  dbSelect = (DBSelect) initializeDBStatement(dbSelect);
  return dbSelect;
 }

 public static DBModify getDBModify() {
  DBModify dbModify = new DBModify();
  dbModify = (DBModify) initializeDBStatement(dbModify);
  return dbModify;
 }

 public static DBProcedureCall getDBProcedureCall() {
  DBProcedureCall dbProcedureCall = new DBProcedureCall();
  dbProcedureCall = (DBProcedureCall) initializeDBStatement(dbProcedureCall);
  return dbProcedureCall;
 }

 public static DataSource getDataSource() throws ServiceLocatorException {
  //write a logic to get DataSource
 }

 private static DBStatement initializeDBStatement(DBStatement dbStatement) {
  try {
   Connection conn = getDataSource().getConnection();
   dbStatement.setConnection(conn);
   dbStatement.setOptimizeForNoListeners(true);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return dbStatement;
 } 
}

DBConnectionSpec

If we want to establish connection without any of connection pooling mechanism, this class helps to do that.

private static DBStatement initializeDBStatement(DBStatement dbStatement) {
 try {
 DBConnectionSpec connectionSpec = new DBConnectionSpec();
 connectionSpec.setUsername(user);
 connectionSpec.setPassword(password);
 connectionSpec.setDriverName(driver);
 connectionSpec.setUrl(url);
 
 dbStatement.setConnectionSpec(connectionSpec);
 } catch (Exception e) {
    e.printStackTrace();
 }
}

DBSelectMetaData

DBSelectMetaData stores meta data of DBSelect which will be resulted out after execution

DBSelectMetaData dm= dbSelect.getMetaData();
for(int i=0;i<dm.getColumnCount();i++)
{
System.out.println(dm.getColumnName(i)+" Type:"+dm.getColumnType());
}

DBSelect and ResultSet

Create DBSelect statement and tag with DB connection using DBStatementFactory class and then set SQL command using setCommand(). Once all set to go then execute() has to be called to retrieve data from DB.


String SELECT_ALL_SHIRTS_CATALOGS = "SELECT SHIRTNAME, SHIRTDESC FROM catalogs";
public void displayAllShirtsCatalogs() throws Exception { 
  DBSelect dbSelect = null;
  try {
   DBSelect dbSelect = DBStatementFactory.getDBSelect();
   dbSelect.setCommand(SELECT_ALL_SHIRTS_CATALOGS);

   dbSelect.execute();

   if (dbSelect.onRow()) {
    int size = dbSelect.getRowCount();
    do {
  System.out.println(dbSelect.getColumn(1) 
  + " " + dbSelect.getColumn(2)); 
    } while (dbSelect.next());
   }

  } finally {
   dbSelect.close(DBStatement.LEVEL_CONNECTION);
  } 
 }
 

Monday, January 25, 2010

JDBC

Java Database Connectivity (JDBC)

JDBC is the industry standard for database agnostic connectivity, where developer can read/write data from/to DBMS, without worry about the platform, DBMS and its implementation. SQL or non-SQL based possible to connect using this JDBC. We have to make a call using JDBC where it takes responsibility of how it has to be translated to DB calls and vice versa.

Types of JDBC Drivers

JDBC-ODBC bridge
access through ODBC drivers. Performance of this connection is not good compare with others
Native-API partly Java technology-enabled driver
Converts JDBC calls into direct DB API calls. Some DB binaries has to be placed in client system.
Net-protocol fully Java technology-enabled driver
JDBC API calls converted into middleware understanable calls, same will convert back to DBMS understandable call by middleware server. Hence, DB vendors has to support and adhere with middleware and vice versa.
Native-protocol fully Java technology-enabled driver
converts JDBC API calls to network protocol which is supported by DBMS vendor. Hence, client machine directly access DB without middleware.

Connection Establishment

After successful installation of Database, We have to start the Database with listening port number, default port numbers MySQL(3306), Oracle(1521). Following steps has to be catered in our implementation to establish connection.
  1. Load and Register Driver class, which has static block to set DriverInfo (driver, driverClass, driverClassName) using java.sql.DriverManager.registerDriver.
    Class.forName("oracle.jdbc.OracleDriver");
  2. Form Connection URL, which helps to identify which DB driver has to be used as like jdbc:subprotocol:subname
     String url = "jdbc:oracle:thin:@xyz.oracle.com:1521/xyz" ;
  3. Set values for properties like username and password, and etc.,or pass credentials while creating/fetching connection from DriverManager.
    
     java.util.Properties info = new java.util.Properties();
     info.put("user", user);
     info.put("password", password);
  4. Fetch/create connection from DriverManager
    
    java.sql.Connection conn=getConnection(url, info);
    or
    java.sql.Connection conn=getConnection(url, user, password);
    

Loading Class

Class.forName(className) is equivalent to Class.forName(className, true, ClassLoader.getCallerClassLoader()), where true says that className class can be intialized(static blocks get executed). Almost all the the Driver has the following code to register DriverInfo to DriverManager


static 
{
 try
 {
 DriverManager.registerDriver(new Driver());
 }
 catch(SQLException E)
 {
 throw new RuntimeException("Can't register driver!");
 }
}

DataSource

Instead of creating connection from DriverManager and maintaing it, we can fetch the unused connection from javax.sql.DataSource, which will take care of lifecycle of connection. DataSource comes with three different implementation flavour Basic, ConnectionPool, Distributed

In server based application, we can access DataSource object through JNDI look up.


InitialContext ic = new InitialContext(); 
DataSource ds = ic.lookup("java:jdbc/mydb/MyDataSource");
Connection con = ds.getConnection(); 

In standalone application also, we can


DataSource ds = new OracleDataSource();
 ds.setURL(url);
 ds.setUser(user)
 ds.setPassword(password); 
Connection con = ds.getConnection(); 

Statement

Once Connection establishment is completed, we can get start with reading/writing to Database. To input our requirement to DB, we need an interface that is nothing but a java.sql.Statement.

Statement comes in three different flavour

  1. Statement - to run Dynamic SQL queries, which will be parsed and compiled everytime it gets executed.
  2. Prepare Statement - to run parameterized SQL query with getting benefit of precompilation of SQL
  3. Callable Statement - to execute stored procedures

Statement can executed using the following API's

  1. execute - executes SQL query and returns true if found first result as ResultSet
  2. executeQuery - used to execute SQL SELECT query and returns ResultSet
  3. executeBatch - executes all the SQL queries which are added using Statement.addBatch(sqlQuery)
  4. executeUpdate - used to execute SQL UPDATE, DELETE, INSERT and TRUNCATE queries and results number of impacted records count

Auto Generated Keys

Generally, we specify primary key columns to auto generate value by DB to avoid duplications. We may need this value in caller place to utilize in other business. Best example would be, in PurchaseOrder scenario, where master entry created with buyer details and date of order in PurchaseOrderMaster entry, where item and quantity lists are captured in PurchaseOrderChild table.

We can request DB driver to send back the generated key to caller by passing Statement.RETURN_GENERATED_KEYS in execute, and executeUpdate APIs.


Statement stmt = con.createStatement();
if(stmt.execute(insertStmt, Statement.RETURN_GENERATED_KEYS))
{
ResultSet rs=stmt.getGeneratedKeys();
while (rs.next()) {
System.out.println(rs.getString(1));
}
}

Maximum Rows and Timeout

Additionally, We can set property like maximum number of rows need to be fetched, maximum time to wait for query to process(Timeout), maximum field size, cursor name, fetching direction and etc.,


stmt.setMaxRows(50);
stmt.setFetchDirection(ResultSet.FETCH_REVERSE);

ResultSet

java.sql.ResultSet captures outcome from DB call. It gives details about the column, and its value. If SQL SELECT statement executed using executeQuery API then we do get ResultSet object as output. This resulted object has cursor which positioned before the first row of result. We have to call next() API to get into first row of result. If no argument passed, while creating connection then we can move the cursor only towards forward

If we wants to move cursor forward and backward then we have to pass ResultSet.TYPE_SCROLL_INSENSITIVE or ResultSet.TYPE_SCROLL_SENSITIVE. We have following APIs to ease the cursor movement - next(), previous(), first(), last(), beforeFirst(), afterLast(), relative(int rows), and absolute(int row)

We can eventually update ResultSet which will be updated in DB. To enable this, we have pass second argument as ResultSet.CONCUR_UPDATABLE, default is ResultSet.CONCUR_READ_ONLY


Statement stmt = con.createStatement(
 ResultSet.TYPE_SCROLL_SENSITIVE,
 ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT 1 FROM DUAL");

ResultSet comes with row manipulating APIs like insertRow(), deleteRow(), updateRow() and refreshRow().

Similarly, ResultSet helps to get value of columns either passing number or column name. First column is refered using 1 and its go on.


int Id=rs.getInt(1);
float amt= rs.getFloat("amount");
Blob blob=rs.getBlob("policy");
Clob clob=rs.getClob("policyinclob");
Reader reader=rs.getCharacterStream("policy");
InputStream is=rs.getBinaryStream("policy");

Release resource

We have established a connection and ran Statement and retrieved result. What next ?

We have to release used resource like Sonnection, statement, and ResultSet. Since these are making physical connection to DB, it is application responsibility to notify Driver to release or pool the resources. close() api called in these resources to release. if connection pooling is enabled, then connection will be collected for reuse.


rs.close();
stmt.close();
conn.close();

Read more : JDBC Basic | JDBC Overview

How to read data from Blob?

java.sql.Blob interface exposes two APIs to read bytes from Blob object.


Blob blob=rs.getBlob("policy");

InputStream is = blob.getBinaryStream() ; //option 1
byte[] bytes = blob.getBytes(1, (int) blob.length()); //option 2

Saturday, April 25, 2009

Unexpected exception while enlisting XAConnection:


Caused by: java.sql.SQLException: Unexpected exception while enlisting XAConnection 
java.sql.SQLException: Transaction rolled back: Transaction timed out after 50 seconds
BEA1-450F175C33A65FA1D8A0
at weblogic.jdbc.jta.DataSource.enlist(DataSource.java:1431)
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1331)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:426)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:383)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:346)
at oracle.toplink.jndi.JNDIConnector.connect(JNDIConnector.java:123)
at oracle.toplink.jndi.JNDIConnector.connect(JNDIConnector.java:84)
at oracle.toplink.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:153)
at oracle.toplink.internal.databaseaccess.DatasourceAccessor.connectInternal(DatasourceAccessor.java:273)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.connectInternal(DatabaseAccessor.java:230)
at oracle.toplink.internal.databaseaccess.DatasourceAccessor.reconnect(DatasourceAccessor.java:478)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.reconnect(DatabaseAccessor.java:1342)
at oracle.toplink.internal.databaseaccess.DatasourceAccessor.incrementCallCount(DatasourceAccessor.java:251)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:511)
at oracle.toplink.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:467)
at oracle.toplink.internal.sessions.AbstractSession.executeCall(AbstractSession.java:800)
at oracle.toplink.internal.sessions.IsolatedClientSession.executeCall(IsolatedClientSession.java:115)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeCall(
DatasourceCallQueryMechanism.java:193)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeCall(
DatasourceCallQueryMechanism.java:179)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeNoSelectCall(
DatasourceCallQueryMechanism.java:222)
at oracle.toplink.internal.queryframework.DatasourceCallQueryMechanism.executeNoSelect(
DatasourceCallQueryMechanism.java:202)
at oracle.toplink.queryframework.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:55)
at oracle.toplink.queryframework.DatabaseQuery.execute(DatabaseQuery.java:674)
at oracle.toplink.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:597)
at oracle.toplink.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2741)

This exception thrown out due to the JTA time out specified in application server exceeded for the connection. Here in this exception, 50seconds specified and crossed the limit. We can increase this number(upto 600s) and test the application , if still problem persist, then we have to eye on Database.

Read More about ConnectionDeadSQLException

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com