Kava Pava Gava Tava Nava Zava Java

          everything about Java
          隨筆 - 15, 文章 - 0, 評論 - 1, 引用 - 0
          數據加載中……

          Set oracle.jdbc.V8Compatible=true when using higher version JDBC driver to access 8i databases, or strange things will happen

          Sometimes days work - encountering the problem, confusing, testing, replacing this and that, getting source code, tracing into source codes, searching on Internet, and finally you get an answer which can be phased in just one sentence. This one is the case. The answer I finally get is:

          You shall set oracle.jdbc.V8Compatible=true when using higher version JDBC driver to access 8i databases, or strange things will happen.

          Here's my story...

          Strange things happened when working with hibernate + oracle database. At first I thought it was hibernate that massed things up and for days I was tracing between lines of hibernate source codes and observing what was hibernate doing. At last I thought that this is a JDBC driver bug. So, I wrote a test without hibernate but doing what hibernate had done to reproduce the bug. Here it is:

          (1) The schema (generated by hbm2ddl):


              
          drop table BizCase cascade constraints;

              
          drop table TimeSheetItem cascade constraints;

              
          drop sequence hibernate_sequence;

              
          create table BizCase (
                  id 
          number(10,0not null,
                  created date,
                  description 
          varchar2(500),
                  status 
          varchar2(2),
                  title 
          varchar2(200not null,
                  typeid 
          varchar2(2),
                  
          primary key (id)
              );

              
          create table TimeSheetItem (
                  id 
          number(10,0not null,
                  description 
          varchar2(255not null,
                  hours 
          float not null,
                  occurDate date 
          not null,
                  status 
          varchar2(2),
                  bizCase_id 
          number(10,0not null,
                  
          primary key (id)
              );

              
          alter table TimeSheetItem 
                  
          add constraint FK_TIMESHEET_BIZCASE 
                  
          foreign key (bizCase_id) 
                  
          references BizCase;

              
          create sequence hibernate_sequence;

          Note: if the id columns are defined as "id number not null", i.e. without precision and scale, the bug won't show up.

          (2) The test code, simple and straight-forward:

          import java.sql.*;

          public class JDBCTest {

            
          public static void main (String args []) throws SQLException
            {

              
          // open connection
              DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
              Connection conn 
          =
                DriverManager.getConnection (
          "jdbc:oracle:thin:@your.oracleserver.com:1521:yourdbname""username""password");

              
          // get id from sequence, as hibernate did
              Statement stmt = conn.createStatement ();
              ResultSet rset 
          = stmt.executeQuery ("select hibernate_sequence.nextval from dual");
              rset.next();
              Integer seq 
          = rset.getInt(1);
              System.out.println(
          "Sequence is "+String.valueOf(seq));

              
          // insert bizcase
              PreparedStatement insert = conn.prepareStatement("insert into BizCase (created, description, status, title, typeid, id) values (?, ?, ?, ?, ?, ?)");

              
          // the following lines do what exactly hibernate did
              Timestamp ts = new Timestamp( ( (java.util.Date) (new java.util.Date()) ).getTime() );
              insert.setTimestamp(
          1, ts);
              insert.setString(
          2"test case");
              insert.setString(
          3"OP");
              insert.setString(
          4"test case title");
              insert.setString(
          5"TP");
              insert.setInt(
          6, ( (Integer) seq ).intValue());

              insert.addBatch();
              
          int[] ret = insert.executeBatch();
              System.out.print(
          "Insert is successful and returned {");
              
          for (int i : ret) 
                  System.out.print(String.valueOf(i)
          +" ");
              System.out.println(
          "}");
              conn.commit();
              insert.close();
              
              System.out.println(
          "Commit successful. ");
              conn.close();
            }
          }

          (3) Output from running the above:

          D:\>java -cp C:\Oracle\Ora81\jdbc\lib\classes12.zip;. JDBCTest
          Sequence is 1
          Insert is successful and returned {-2 }
          Commit successful.

          D:\>java -cp C:\Oracle\Ora81\jdbc\lib\classes12.zip;. JDBCTest
          Sequence is 2
          Insert is successful and returned {-2 }
          Commit successful.

          D:\>java -cp C:\Oracle\Ora81\jdbc\lib\classes12.zip;. JDBCTest
          Sequence is 3
          Insert is successful and returned {-2 }
          Commit successful.

          ......


          (4) The bug, from sqlplus, see what's inserted into the database:
          SQL> select id, title from bizcase;

                  ID TITLE
          ---------- ----------------------------------------
          -(.000E+46 test case title
          8.1000E+49 test case title
          4.5000E+25 test case title


          Apparently, the id column is corrupted, even beyond what is defined in schema, and this cause Sqlplus crash from time to time at client side.

          (5) Test matrix - which driver has this bug?

          Driver Result
          with classes12.zip at C:\Oracle\Ora81\jdbc\lib, Oracle JDBC Drivers release 8.1.6 OK, no problem found
          with "oracle 8.1.7 driver\classes12.zip", oracle 8.1.7 driver OK, no problem found
          with "oracle 10i\classes12.jar", oracle 10i driver ID corrputed. Bug
          with "oracle9i driver\classes12.jar", oracle 9i driver ID corrputed. Bug
          with "oracle 10i\ojdbc14.jar", oracle 10i driver ID corrputed. Bug
          with "oracle9i driver\ojdbc14.jar", oracle 9i driver ID corrputed. Bug

          (6) Solution:

          Searching with google, some other guys seem to have noticed the same or a related issue. See (http://forums.oracle.com/forums/thread.jspa?messageID=1659839). It suggests "" props.put("oracle.jdbc.V8Compatible", "true"); "".

          In searching, crossed this guy's blog. Finally, someone encuntered the same problem with me. (http://sorphi.javaeye.com/blog/290045) If I had seen this one earlier, it would have saved me a lot of efforts.

          Change the codes of the test application like this, and test again with those drivers, the problem disappeared.

          DriverManager.registerDriver(new oracle.jdbc.OracleDriver());

          java.util.Properties prop 
          = new java.util.Properties();
          prop.put(
          "oracle.jdbc.V8Compatible""true"); 
          prop.put(
          "user""user_name");
          prop.put(
          "password""your_password");

          Connection conn 
          = DriverManager.getConnection(
                          
          "jdbc:oracle:thin:@your.server.com:1521:dbname", prop);

          To set the property in hibernate, add this line into hibernate.cfg.xml:

          <property name="hibernate.connection.oracle.jdbc.V8Compatible">true</property>

          After solving the problem, I can find articles suggesting "oracle.jdbc.V8Compatible" everywhere. However, before I knew this, I need to trace from line to line in the source codes. The lesson is, to the library writters:

          PLEASE:
           
          Do more check, find problem earlier, and throw an exception with clear message indicating what went wrong and how to fix.
           
          THANK YOU

          - FROM DISTRESSED DEVELOPER USING YOUR LIB.

          posted on 2009-12-09 15:04 bing 閱讀(4053) 評論(0)  編輯  收藏 所屬分類: Hibernate

          主站蜘蛛池模板: 云和县| 侯马市| 和平县| 安达市| 张北县| 萨迦县| 吴川市| 安国市| 娄底市| 玉龙| 屏南县| 峨眉山市| 济阳县| 大姚县| 日土县| 襄垣县| 永吉县| 耿马| 石景山区| 临湘市| 海宁市| 柳林县| 日喀则市| 大新县| 临沂市| 建德市| 卓尼县| 仙桃市| 天镇县| 宁武县| 富平县| 阳曲县| 榕江县| 阿城市| 浠水县| 深水埗区| 广昌县| 手机| 嘉荫县| 安丘市| 景德镇市|