0 Replies Latest reply on Jul 22, 2009 10:50 AM by depryf

    How to access OraclePreparedStatement from JBoss wrapped pre

      We are using JBoss with Oracle.

      We use Hibernate to map our entities and we recently discovered that versioned entities cannot use batching because Oracle's OJDBC does not implement the standard batching model.

      If you are interested in that particular issue, you can find a detailed description of the problem and the solution here:
      https://forums.hibernate.org/viewtopic.php?t=978756
      http://opensource.atlassian.com/projects/hibernate/browse/HHH-3360

      Both those solutions a based on accessing the OraclePreparedStatement and using Oracle-specific methods on it. When testing the solution without JBoss (through a JUnit test), the prepared statement used by Hibernate is an instance of an OraclePreparedStatement and the solution works fine.

      But when using JBoss, the prepared statement is a JBoss-specific wrapped prepared statement (WrappedPreparedStatement). We can easily unwrap it, but what we get is still not an OraclePreparedStatement, it is an OraclePreparedStatementWrapper, which is a private class from the OJDBC. We did find a way to actually get to the OraclePreparedStatement but it is really not pretty. It involves accessing private fields and calling private methods through reflection, which is a terrible solution. Here is an example of calling the Oracle-specific "setExecuteBatch(int)" method:

       private void setExecuteBatch(PreparedStatement stmt, int value) throws SQLException {
       if (stmt instanceof OraclePreparedStatement)
       ((OraclePreparedStatement)stmt).setExecuteBatch(value);
       else if (stmt instanceof WrappedPreparedStatement) {
       try {
       Object oracleStatement1 = ((WrappedPreparedStatement)stmt).getUnderlyingStatement();
       Field f = oracleStatement1.getClass().getDeclaredField("preparedStatement");
       f.setAccessible(true);
       Object oracleStatement2 = f.get(oracleStatement1);
       Method m = oracleStatement2.getClass().getMethod("setExecuteBatch", int.class);
       m.setAccessible(true);
       m.invoke(oracleStatement2, value);
       }
       catch (Exception e) {
       throw new RuntimeException("Unablet to get Oracle statement from wrapped JBoss statement", e);
       }
       }
       else
       throw new RuntimeException("Don't know how to access Oracle statement...");
       }
      


      This works but will most likely break when we update to a new OJDBC.

      We were wondering if anybody else ran into this problem of having to access the Oracle prepared statement through JBoss and if there is a better way of doing it.

      Thank you!