db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mka...@apache.org
Subject cvs commit: db-ojb/src/java/org/apache/ojb/broker/platforms PlatformOracleImpl.java PlatformOracle9iImpl.java
Date Sun, 15 Aug 2004 22:39:11 GMT
mkalen      2004/08/15 15:39:11

  Modified:    src/java/org/apache/ojb/broker/platforms
                        PlatformOracleImpl.java PlatformOracle9iImpl.java
  Log:
  OJB272: Clarify Oracle platform exceptions thrown on big CLOB BLOB when native Oracle LOB
handling is N/A.
  
  Revision  Changes    Path
  1.21      +64 -28    db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java
  
  Index: PlatformOracleImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- PlatformOracleImpl.java	22 May 2004 09:55:33 -0000	1.20
  +++ PlatformOracleImpl.java	15 Aug 2004 22:39:10 -0000	1.21
  @@ -34,19 +34,30 @@
   
   /**
    * This class is a concrete implementation of <code>Platform</code>. Provides
an implementation
  - * that works around some issues with Oracle in general and Oracle's Thin driver in particular..
  - * 
  - * @author <a href="mailto:thma@apache.org">Thomas Mahler <a>
  + * that works around some issues with Oracle in general and Oracle's Thin driver in particular.
  + *
  + * @author <a href="mailto:thma@apache.org">Thomas Mahler</a>
  + * @author <a href="mailto:mkalen@apache.org">Martin Kal&eacute;n</a>
    * @version $Id$
    */
  -
   public class PlatformOracleImpl extends PlatformDefaultImpl
   {
  -    protected static final String THIN_URL_PREFIX = "jdbc:oracle:thin";
  -    // Oracle:thin handles direct BLOB insert <= 4000 and update <= 2000
  -    protected static final int THIN_BLOB_MAX_SIZE = 2000;
  -    // Oracle:thin handles direct CLOB insert and update <= 4000
  -    protected static final int THIN_CLOB_MAX_SIZE = 4000;
  +    protected static final String OCI_URL_PREFIX = "jdbc:oracle:oci";
  +    // Only oracle:oci handles direct BLOB insert > 4000 and update > 2000
  +    protected static final int NON_OCI_BLOB_MAX_SIZE = 2000;
  +    // Only oracle:oci handles direct CLOB insert and update > 4000
  +    protected static final int NON_OCI_CLOB_MAX_SIZE = 4000;
  +
  +    protected static final String NOT_LARGE_BLOB_CAPABLE =
  +            "BLOB values with length>" + NON_OCI_BLOB_MAX_SIZE +
  +            " can only be inserted using Oracle9i platform in an unmanaged" +
  +            " environment or oracle platform with Oracle OCI driver";
  +
  +    protected static final String NOT_LARGE_CLOB_CAPABLE =
  +            "CLOB values with length>" + NON_OCI_CLOB_MAX_SIZE +
  +            " can only be inserted using Oracle9i platform in an unmanaged" +
  +            " environment or oracle platform with Oracle OCI driver";
  +
       private Logger logger = LoggerFactory.getLogger(PlatformOracleImpl.class);
   
       /**
  @@ -80,13 +91,20 @@
           {
               byte buf[] = (byte[]) value;
               int length = buf.length;
  -            if (isUsingOracleThinDriver(ps.getConnection()) && length > THIN_BLOB_MAX_SIZE)
  +            if (!isUsingOracleOCIDriver(ps.getConnection()) && length > NON_OCI_BLOB_MAX_SIZE)
               {
  -                throw new SQLException(
  -                        "Oracle thin driver cannot update BLOB values with length>2000.
(Consider using Oracle9i as OJB platform.)");
  +                logger.error(NOT_LARGE_CLOB_CAPABLE);
  +                StringBuffer msg = new StringBuffer();
  +                msg.append("DB URL: ").append(getDbUrl(ps.getConnection()));
  +                msg.append(", connection class: ");
  +                msg.append(ps.getConnection().getClass().getName());
  +                msg.append(", value class ");
  +                msg.append(value.getClass().getName());
  +                logger.error(msg);
  +                throw new SQLException(NOT_LARGE_BLOB_CAPABLE);
               }
               ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
  -            changePreparedStatementResultSetType(ps);
  +            //changePreparedStatementResultSetType(ps);
               ps.setBinaryStream(index, inputStream, length);
           }
           else if (value instanceof Double)
  @@ -125,10 +143,17 @@
                   reader = new InputStreamReader(inputStream);
                   length = buf.length;
               }
  -            if (isUsingOracleThinDriver(ps.getConnection()) && length > THIN_CLOB_MAX_SIZE)
  +            if (!isUsingOracleOCIDriver(ps.getConnection()) && length > NON_OCI_CLOB_MAX_SIZE)
               {
  -                throw new SQLException(
  -                        "Oracle thin driver cannot insert CLOB values with length>4000.
(Consider using Oracle9i as OJB platform.)");
  +                logger.error(NOT_LARGE_CLOB_CAPABLE);
  +                StringBuffer msg = new StringBuffer();
  +                msg.append("DB URL: ").append(getDbUrl(ps.getConnection()));
  +                msg.append(", connection class: ");
  +                msg.append(ps.getConnection().getClass().getName());
  +                msg.append(", value class ");
  +                msg.append(value.getClass().getName());
  +                logger.error(msg);
  +                throw new SQLException(NOT_LARGE_CLOB_CAPABLE);
               }
               ps.setCharacterStream(index, reader, length);
           }
  @@ -188,17 +213,15 @@
       }
   
       /**
  -     * Checks if the supplied connection is using the Oracle thin driver.
  -     * 
  -     * @param conn database connection for which to check JDBC-driver
  -     * @return <code>true</code> if the connection is using Oracle thin driver,
<code>false</code>
  -     *         otherwise.
  +     * Returns the JDBC URL used for the specified connection.
  +     * @param conn the database connection for which to check JDBC URL
  +     * @return the JDBC URL or an empty String on error
  +     * (never <code>null</code>).
        */
  -    protected static boolean isUsingOracleThinDriver(Connection conn)
  -    {
  +    protected static String getDbUrl(Connection conn) {
           if (conn == null)
           {
  -            return false;
  +            return "";
           }
           final DatabaseMetaData dbMetaData;
           final String dbUrl;
  @@ -206,16 +229,29 @@
           {
               dbMetaData = conn.getMetaData();
               dbUrl = dbMetaData.getURL();
  -            if (dbUrl != null && dbUrl.startsWith(THIN_URL_PREFIX))
  +            if (dbUrl != null)
               {
  -                return true;
  +                return dbUrl;
               }
           }
           catch (Exception e)
           {
               // ignore it
           }
  -        return false;
  +        return "";
  +    }
  +
  +    /**
  +     * Checks if the supplied connection is using the Oracle OCI driver.
  +     * 
  +     * @param conn database connection for which to check JDBC-driver
  +     * @return <code>true</code> if the connection is using Oracle OCI driver,
  +     *         <code>false</code> otherwise.
  +     */
  +    protected static boolean isUsingOracleOCIDriver(Connection conn)
  +    {
  +        String dbUrl = getDbUrl(conn);
  +        return dbUrl != null && dbUrl.startsWith(OCI_URL_PREFIX);
       }
   
   }
  
  
  
  1.14      +61 -32    db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java
  
  Index: PlatformOracle9iImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- PlatformOracle9iImpl.java	22 May 2004 09:55:33 -0000	1.13
  +++ PlatformOracle9iImpl.java	15 Aug 2004 22:39:11 -0000	1.14
  @@ -19,6 +19,8 @@
   import org.apache.ojb.broker.metadata.JdbcType;
   import org.apache.ojb.broker.util.ClassHelper;
   import org.apache.ojb.broker.util.JdbcTypesHelper;
  +import org.apache.ojb.broker.util.logging.Logger;
  +import org.apache.ojb.broker.util.logging.LoggerFactory;
   
   import java.io.ByteArrayInputStream;
   import java.lang.reflect.Method;
  @@ -32,8 +34,7 @@
   
   /**
    * This class is a concrete implementation of <code>Platform</code>. Provides
  - * an implementation that works around some issues with Oracle in general and
  - * Oracle 9i's Thin driver in particular.
  + * an implementation that uses Oracle specific optimizations and LOB-handling.
    *
    * Optimization: Oracle Batching (not standard JDBC batching)
    * see http://technet.oracle.com/products/oracle9i/daily/jun07.html
  @@ -49,7 +50,7 @@
    *
    * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
    * @author <a href="mailto:erik@cj.com">Erik Forkalsrud</a>
  - * @author <a href="mailto:martin.kalen@curalia.se">Martin Kal&eacute;n</a>
  + * @author <a href="mailto:mkalen@apache.org">Martin Kal&eacute;n</a>
    * @version CVS $Id$
    * @see Platform
    * @see PlatformDefaultImpl
  @@ -57,6 +58,8 @@
    */
   public class PlatformOracle9iImpl extends PlatformOracleImpl
   {
  +    private Logger logger = LoggerFactory.getLogger(PlatformOracle9iImpl.class);
  +
       protected static final int STATEMENT_CACHE_SIZE = 100;
       protected static final int ROW_PREFETCH_SIZE = 100;
   
  @@ -244,8 +247,8 @@
       /** @see Platform#setObjectForStatement */
       public void setObjectForStatement(PreparedStatement ps, int index, Object value, int
sqlType) throws SQLException
       {
  -        boolean blobHandlingSupported = false;
  -        boolean clobHandlingSupported = false;
  +        boolean nativeOraBlobsSupported = false;
  +        boolean nativeOraClobsSupported = false;
           Method methodSetBlob = null;
           Method methodSetClob = null;
   
  @@ -256,11 +259,15 @@
               {
                   Class clobClass = ClassHelper.getClass("oracle.sql.CLOB", false);
                   methodSetClob = ClassHelper.getMethod(ps, "setCLOB", new Class[]{Integer.TYPE,
clobClass});
  -                clobHandlingSupported = methodSetClob != null;
  +                nativeOraClobsSupported = methodSetClob != null;
  +                if (!nativeOraClobsSupported && logger.isDebugEnabled())
  +                {
  +                    logger.debug("Oracle CLOB JDBC extensions not available for connection
" + ps.getConnection().getClass());
  +                }
               }
  -            catch (Exception ignore)
  +            catch (Exception e)
               {
  -                // ignore it
  +                logger.warn("Exception while checking for Oracle CLOB JDBC extensions",
e);
               }
           }
           else if (sqlType == Types.BLOB)
  @@ -269,11 +276,15 @@
               {
                   Class blobClass = ClassHelper.getClass("oracle.sql.BLOB", false);
                   methodSetBlob = ClassHelper.getMethod(ps, "setBLOB", new Class[]{Integer.TYPE,
blobClass});
  -                blobHandlingSupported = methodSetBlob != null;
  +                nativeOraBlobsSupported = methodSetBlob != null;
  +                if (!nativeOraBlobsSupported && logger.isDebugEnabled())
  +                {
  +                    logger.debug("Oracle CLOB JDBC extensions not available for connection
" + ps.getConnection().getClass());
  +                }
               }
  -            catch (Exception ignore)
  +            catch (Exception e)
               {
  -                // ignore it
  +                logger.warn("Exception while checking for Oracle BLOB JDBC extensions",
e);
               }
           }
   
  @@ -299,30 +310,48 @@
           {
               ps.setLong(index, ((Long) value).longValue());
           }
  -        else if (sqlType == Types.CLOB && clobHandlingSupported && value
instanceof String)
  +        else if (sqlType == Types.CLOB && value instanceof String)
           {
  -            // TODO: If using Oracle update batching with the thin driver, throw exception
on 4k limit
  -            try
  -            {
  -                Object clob = Oracle9iLobHandler.createCLOBFromString(ps.getConnection(),
(String) value);
  -                methodSetClob.invoke(ps, new Object[]{new Integer(index), clob});
  -            }
  -            catch (Exception e)
  +            // First try native Oracle CLOB handling
  +            if (nativeOraClobsSupported)
               {
  -                throw new SQLException(e.getLocalizedMessage());
  +                // TODO: If using Oracle update batching with the thin driver, throw exception
on 4k limit
  +                try
  +                {
  +                    Object clob = Oracle9iLobHandler.createCLOBFromString(ps.getConnection(),
(String) value);
  +                    methodSetClob.invoke(ps, new Object[]{new Integer(index), clob});
  +                }
  +                catch (Exception e)
  +                {
  +                    throw new SQLException(e.getLocalizedMessage());
  +                }
  +            }
  +            else
  +            // Fall back to default Oracle platform capabilities
  +            {
  +                super.setObjectForStatement(ps, index, value, sqlType);
  +            }
  +        }
  +        else if (sqlType == Types.BLOB && value instanceof byte[])
  +        {
  +            // First try native Oracle BLOB handling
  +            if (nativeOraBlobsSupported)
  +            {
  +                // TODO: If using Oracle update batching with the thin driver, throw exception
on 2k limit
  +                try
  +                {
  +                    Object blob = Oracle9iLobHandler.createBLOBFromByteArray(ps.getConnection(),
(byte[]) value);
  +                    methodSetBlob.invoke(ps, new Object[]{new Integer(index), blob});
  +                }
  +                catch (Exception e)
  +                {
  +                    throw new SQLException(e.getLocalizedMessage());
  +                }
               }
  -        }
  -        else if (sqlType == Types.BLOB && blobHandlingSupported && value
instanceof byte[])
  -        {
  -            // TODO: If using Oracle update batching with the thin driver, throw exception
on 2k limit
  -            try
  -            {
  -                Object blob = Oracle9iLobHandler.createBLOBFromByteArray(ps.getConnection(),
(byte[]) value);
  -                methodSetBlob.invoke(ps, new Object[]{new Integer(index), blob});
  -            }
  -            catch (Exception e)
  +            else
  +            // Fall back to default Oracle platform capabilities
               {
  -                throw new SQLException(e.getLocalizedMessage());
  +                super.setObjectForStatement(ps, index, value, sqlType);
               }
           }
           else
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message