Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsAccessImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsAccessImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsAccessImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsAccessImpl.java Fri Jan 12 10:19:39 2007
@@ -23,12 +23,19 @@
import org.apache.ojb.broker.query.LikeCriteria;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+
/**
* @author <a href="mailto:[email protected]">Jakob Braeuchi</a>
* @version $Id$
*/
public class PlatformMsAccessImpl extends PlatformDefaultImpl
{
+ public PlatformMsAccessImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
/**
* @see Platform#setObjectForStatement(PreparedStatement, int, Object, int)
*/
@@ -62,7 +69,7 @@
// ps.setCharacterStream(index, new StringReader(s), s.length());
// for MSACCESS :
byte[] bytes = s.getBytes();
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ps.setAsciiStream(index, bais, bytes.length);
}
else
@@ -82,9 +89,9 @@
}
else
{
- super.setObjectForStatement(ps, index, value, sqlType);
+ super.setObjectForStatement(ps, index, value, sqlType);
}
- }
+ }
/**
* @see Platform#beforeStatementClose(Statement stmt, ResultSet rs)
@@ -104,30 +111,30 @@
}
}
}
-
+
/**
* Answer the Character for Concatenation
*/
protected String getConcatenationCharacter()
{
return "&";
- }
-
+ }
+
/**
* @see org.apache.ojb.broker.platforms.Platform#getEscapeClause(org.apache.ojb.broker.query.LikeCriteria)
*/
public String getEscapeClause(LikeCriteria aCriteria)
{
// TODO: implement ms-access escaping
- return "";
+ return "";
}
-
-
+
+
/**
* @see org.apache.ojb.broker.platforms.PlatformDefaultImpl#getQuotedName(java.lang.String)
*/
protected String getQuotedName(String aString)
{
- return '[' + aString + ']';
+ return '[' + aString + ']';
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java Fri Jan 12 10:19:39 2007
@@ -20,6 +20,8 @@
import java.sql.Types;
import java.sql.SQLException;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific behavior for the
* Microsoft SQL Server platform.
@@ -28,6 +30,11 @@
*/
public class PlatformMsSQLServerImpl extends PlatformDefaultImpl
{
+ public PlatformMsSQLServerImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
/**
* Get join syntax type for this RDBMS - one on of the constants from JoinSyntaxType interface
* MBAIRD: MS SQL Server 2000 actually supports both types, but due to a problem with the sql
@@ -39,7 +46,7 @@
}
public CallableStatement prepareNextValProcedureStatement(Connection con, String procedureName,
- String sequenceName) throws PlatformException
+ String sequenceName) throws PlatformException
{
try
{
@@ -85,6 +92,6 @@
*/
protected String getQuotedName(String aString)
{
- return '[' + aString + ']';
+ return '[' + aString + ']';
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java Fri Jan 12 10:19:39 2007
@@ -27,11 +27,10 @@
import org.apache.ojb.broker.query.LikeCriteria;
import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.commons.lang.SerializationUtils;
/**
- * @version 1.0
- * @author jakob bräuchi
* @version $Id$
*/
public class PlatformMySQLImpl extends PlatformDefaultImpl
@@ -39,6 +38,11 @@
private static final String LAST_INSERT = "SELECT LAST_INSERT_ID() FROM ";
private static final String LIMIT = " LIMIT 1";
+ public PlatformMySQLImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
/*
* @see Platform#setObjectForStatement(PreparedStatement, int, Object, int)
*/
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java Fri Jan 12 10:19:39 2007
@@ -30,8 +30,10 @@
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.ojb.broker.util.ClassHelper;
import org.apache.ojb.broker.util.UnwrapHelper;
+import org.apache.ojb.broker.util.ConvertHelper;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.commons.lang.exception.ExceptionUtils;
/**
* This class is a concrete implementation of <code>Platform</code>. Provides
@@ -56,9 +58,6 @@
* TODO: Optimization: use ROWNUM to minimize the effects of not having server side cursors
* see <a href="http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:127412348064">Ask TOM</A>.
*
- * @author <a href="mailto:[email protected]">Matthew Baird</a>
- * @author <a href="mailto:[email protected]">Martin Kalén</a>
- * @author Contributions from: Erik Forkalsrud, Danilo Tommasina, Thierry Hanot, Don Lyon
* @version CVS $Id$
* @see Platform
* @see PlatformDefaultImpl
@@ -66,16 +65,64 @@
*/
public class PlatformOracle9iImpl extends PlatformOracleImpl
{
- private Logger logger = LoggerFactory.getLogger(PlatformOracle9iImpl.class);
+ private static Logger log = LoggerFactory.getLogger(PlatformOracle9iImpl.class);
/**
+ * Platform attribute of Oracle's native statement cache pool.
+ */
+ protected static final String ATTRIBUTE_STATEMENT_CACHE_SIZE = "platform.oracle.statementCacheSize";
+ /**
+ * Platform attribute of Oracle's native prefetch handling.
+ */
+ protected static final String ATTRIBUTE_PREFETCH_SIZE = "platform.oracle.prefetchSize";
+ /**
+ * Platform attribute to enable Oracle's native batch handling.
+ */
+ protected static final String ATTRIBUTE_BATCH_SIZE = "platform.oracle.batchSize";
+
+ protected static final Class[] PARAM_TYPE_EMPTY = {};
+ protected static final Class[] PARAM_TYPE_INTEGER = {Integer.TYPE};
+ protected static final Class[] PARAM_TYPE_BOOLEAN = {Boolean.TYPE};
+ protected static final Class[] PARAM_TYPE_STRING = {String.class};
+ protected static final Object[] PARAM_EMPTY = new Object[]{};
+ protected static final Object[] PARAM_BOOLEAN_TRUE = new Object[]{Boolean.TRUE};
+
+ protected static String JBOSS_CONN_NAME = "org.jboss.resource.adapter.jdbc.WrappedConnection";
+ protected static String ORA_CONNECTION_CLASS_NAME = "oracle.jdbc.OracleConnection";
+ protected static String ORA_STATEMENT_CLASS_NAME = "oracle.jdbc.OraclePreparedStatement";
+ protected static String ORA_BLOB_CLASS_NAME = "oracle.sql.BLOB";
+ protected static String ORA_CLOB_CLASS_NAME = "oracle.sql.CLOB";
+
+ protected Class JBOSS_CONN_CLASS;
+ protected Class ORA_CONN_CLASS;
+ protected Class ORA_PS_CLASS;
+ protected Class ORA_CLOB_CLASS;
+ protected Class ORA_BLOB_CLASS;
+ protected Class[] PARAM_TYPE_INT_ORACLOB;
+ protected Class[] PARAM_TYPE_INT_ORABLOB;
+ protected Method METHOD_SET_STATEMENT_CACHE_SIZE;
+ protected Method METHOD_SET_IMPLICIT_CACHING_ENABLED;
+ protected Method METHOD_SET_ROW_PREFETCH;
+ protected Method METHOD_SET_BLOB;
+ protected Method METHOD_SET_CLOB;
+ protected boolean oraStatementCachingAvailable;
+ protected boolean oraRowPrefetchAvailable;
+ protected boolean oraLobHandlingAvailable;
+ protected boolean oraBatchAvailable;
+
+ protected static Map m_batchStatementsInProgress = Collections.synchronizedMap(new WeakHashMap());
+ /**
+ * Size of Oracle's native batch handling size.
+ */
+ protected Object[] paramStatementBatchSize;
+ /**
* Number of cached statements per connection,
* when using implicit caching with OracleConnections.
* Set in {@link #initializeJdbcConnection}.
* @see <a href="http://www.apache.org/~mkalen/ojb/broker-tests.html">Profiling page</a>
* for a discussion re sizing
*/
- protected static final int STATEMENT_CACHE_SIZE = 10;
+ protected Object[] paramStatementCacheSize;
/**
* Number of rows pre-fetched by the JDBC-driver for each executed query,
* when using Oracle row pre-fetching with OracleConnections.
@@ -84,46 +131,8 @@
* <em>Note</em>: this setting can be overridden by specifying a
* connection-pool attribute with name="jdbc.defaultRowPrefetch".
* Oracle JDBC-driver default value=10.
- * @see <a href="http://www.apache.org/~mkalen/ojb/broker-tests.html">Profiling page</a>
- * for a discussion re sizing
*/
- protected static final int ROW_PREFETCH_SIZE = 20;
-
- // From Oracle9i JDBC Developer's Guide and Reference:
- // "Batch values between 5 and 30 tend to be the most effective."
- protected static final int STATEMENTS_PER_BATCH = 20;
- protected static Map m_batchStatementsInProgress = Collections.synchronizedMap(new WeakHashMap(STATEMENTS_PER_BATCH));
-
- protected static final Class[] PARAM_TYPE_EMPTY = {};
- protected static final Class[] PARAM_TYPE_INTEGER = {Integer.TYPE};
- protected static final Class[] PARAM_TYPE_BOOLEAN = {Boolean.TYPE};
- protected static final Class[] PARAM_TYPE_STRING = {String.class};
-
- protected static final Object[] PARAM_EMPTY = new Object[]{};
- protected static final Object[] PARAM_STATEMENT_CACHE_SIZE = new Object[]{new Integer(STATEMENT_CACHE_SIZE)};
- protected static final Object[] PARAM_ROW_PREFETCH_SIZE = new Object[]{new Integer(ROW_PREFETCH_SIZE)};
- protected static final Object[] PARAM_STATEMENT_BATCH_SIZE = new Object[]{new Integer(STATEMENTS_PER_BATCH)};
- protected static final Object[] PARAM_BOOLEAN_TRUE = new Object[]{Boolean.TRUE};
-
- protected static final String JBOSS_CONN_NAME =
- "org.jboss.resource.adapter.jdbc.WrappedConnection";
- protected static Class JBOSS_CONN_CLASS = null;
-
- protected static Class ORA_CONN_CLASS;
- protected static Class ORA_PS_CLASS;
- protected static Class ORA_CLOB_CLASS;
- protected static Class ORA_BLOB_CLASS;
- protected static Class[] PARAM_TYPE_INT_ORACLOB;
- protected static Class[] PARAM_TYPE_INT_ORABLOB;
- protected static Method METHOD_SET_STATEMENT_CACHE_SIZE;
- protected static Method METHOD_SET_IMPLICIT_CACHING_ENABLED;
- protected static Method METHOD_SET_ROW_PREFETCH;
- protected static Method METHOD_SET_BLOB = null;
- protected static Method METHOD_SET_CLOB = null;
- protected static boolean ORA_STATEMENT_CACHING_AVAILABLE;
- protected static boolean ORA_ROW_PREFETCH_AVAILABLE;
- protected static boolean ORA_CLOB_HANDLING_AVAILABLE;
- protected static boolean ORA_BLOB_HANDLING_AVAILABLE;
+ protected Object[] paramRowPrefetchSize;
/**
* Helper to unwrap connections and statements.
@@ -131,100 +140,266 @@
protected UnwrapHelper unwrapHelper;
- /**
- * Default constructor.
- */
- public PlatformOracle9iImpl()
+ public PlatformOracle9iImpl(JdbcConnectionDescriptor jcd)
{
- super();
+ super(jcd);
+ initOracleReflectedVars();
}
/**
- * Enables Oracle statement caching and row prefetching if supported by the JDBC-driver.
- * @param jcd the OJB <code>JdbcConnectionDescriptor</code> (metadata) for the connection to be initialized
- * @param conn the <code>Connection</code>-object (physical) to be initialized
- * @see PlatformDefaultImpl#initializeJdbcConnection
- * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html">
- * Oracle TechNet Statement Caching Sample</a>
- * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html">
- * Oracle TechNet Row Pre-fetch Sample<a>
+ * Initializes static variables needed for Oracle-extensions and large BLOB/CLOB support,
+ * attributes set in {@link org.apache.ojb.broker.metadata.JdbcConnectionDescriptor}.
*/
- public void initializeJdbcConnection(final JdbcConnectionDescriptor jcd,
- final Connection conn)
- throws PlatformException
+ private void initOracleReflectedVars()
{
- // Do all the generic initialization in PlatformDefaultImpl first
- super.initializeJdbcConnection(jcd, conn);
+ unwrapHelper = new UnwrapHelper();
+ try
+ {
+ /*
+ Check for Oracle-specific classes, OracleConnection-specific
+ statement caching/row pre-fetch methods and Oracle BLOB/CLOB access methods.
+ We can do this in constructor in spite of possible mixing of instance being
+ able vs unable passed at runtime (since withouth these classes and methods
+ it's impossible to enable ORA-extensions at all even if instances are capable).
+ */
+ ORA_CONN_CLASS = ClassHelper.getClass(ORA_CONNECTION_CLASS_NAME, false);
+ ORA_PS_CLASS = ClassHelper.getClass(ORA_STATEMENT_CLASS_NAME, false);
+ /*
+ The unwrap pattern used in {@link org.apache.ojb.broker.util.UnwrapHelper}
+ to unwrap connection instance to Oracle's specific connection implementation class.
+ */
+ Object[] oracleUnwrapPattern = new Object[] {"oracle 10g", UnwrapHelper.TYPE_METHOD,
+ new Class[]{ORA_CONN_CLASS}, "unwrapCompletely", null, null, null};
+ // add the oracle unwrap pattern
+ unwrapHelper.addUnwrapPattern(oracleUnwrapPattern);
+ }
+ catch(ClassNotFoundException e)
+ {
+ log.info("Can't access Oracle specific driver Connection/Statement classes using class names: "
+ + ORA_CONNECTION_CLASS_NAME + " and " + ORA_STATEMENT_CLASS_NAME, e);
+ }
- // Check for managed environments known to reject Oracle extension at this level
- // (saves us from trying to unwrap just to catch exceptions next)
- final Class connClass = conn.getClass();
- if (JBOSS_CONN_CLASS != null && JBOSS_CONN_CLASS.isAssignableFrom(connClass))
+
+ try
{
- if (logger.isDebugEnabled())
- {
- logger.debug("JBoss detected, Oracle Connection tuning left to J2EE container.");
- }
- return;
+ ORA_CLOB_CLASS = ClassHelper.getClass(ORA_CLOB_CLASS_NAME, false);
+ ORA_BLOB_CLASS = ClassHelper.getClass(ORA_BLOB_CLASS_NAME, false);
+ PARAM_TYPE_INT_ORACLOB = new Class[]{ Integer.TYPE, ORA_CLOB_CLASS };
+ PARAM_TYPE_INT_ORABLOB = new Class[]{ Integer.TYPE, ORA_BLOB_CLASS };
+ METHOD_SET_CLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setCLOB", PARAM_TYPE_INT_ORACLOB);
+ METHOD_SET_BLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setBLOB", PARAM_TYPE_INT_ORABLOB);
+ }
+ catch(ClassNotFoundException e)
+ {
+ log.info("Can't use Oracle specific BLOB/CLOB classes using class names: "
+ + ORA_BLOB_CLASS_NAME + ", " + ORA_CLOB_CLASS_NAME, e);
}
- // Check if this is a wrapped connection and if so unwrap it
- final Connection oraConn = unwrapConnection(conn);
- if (oraConn == null)
+ try
{
- return;
+ METHOD_SET_STATEMENT_CACHE_SIZE =
+ ClassHelper.getMethod(ORA_CONN_CLASS, "setStatementCacheSize", PARAM_TYPE_INTEGER);
+ METHOD_SET_IMPLICIT_CACHING_ENABLED =
+ ClassHelper.getMethod(ORA_CONN_CLASS, "setImplicitCachingEnabled", PARAM_TYPE_BOOLEAN);
+ }
+ catch(Exception e)
+ {
+ log.info("Can't enable Oracle specific implicit statement caching", e);
}
- // At this point we know that we have an OracleConnection instance and can thus
- // try to invoke methods via reflection (if available)
- if (ORA_STATEMENT_CACHING_AVAILABLE)
+
+ try
{
- try
+ METHOD_SET_ROW_PREFETCH = ClassHelper.getMethod(ORA_CONN_CLASS, "setDefaultRowPrefetch", PARAM_TYPE_INTEGER);
+ }
+ catch(Exception e)
+ {
+ log.info("Can't use Oracle specific row prefetch settings", e);
+ }
+
+ oraStatementCachingAvailable = METHOD_SET_STATEMENT_CACHE_SIZE != null && METHOD_SET_IMPLICIT_CACHING_ENABLED != null;
+ oraRowPrefetchAvailable = METHOD_SET_ROW_PREFETCH != null;
+ oraLobHandlingAvailable = METHOD_SET_CLOB != null && METHOD_SET_BLOB != null;
+
+ if(oraStatementCachingAvailable)
+ {
+ String stmtCacheSize = jcd.getAttribute(ATTRIBUTE_STATEMENT_CACHE_SIZE);
+ boolean enabled = false;
+ if(stmtCacheSize != null && stmtCacheSize.length() > 0)
{
- // Set number of cached statements and enable implicit caching
- METHOD_SET_STATEMENT_CACHE_SIZE.invoke(oraConn, PARAM_STATEMENT_CACHE_SIZE);
- METHOD_SET_IMPLICIT_CACHING_ENABLED.invoke(oraConn, PARAM_BOOLEAN_TRUE);
+ try
+ {
+ Integer size = ConvertHelper.toInteger(stmtCacheSize);
+ if(size.intValue() > 0)
+ {
+ paramStatementCacheSize = new Object[]{size};
+ enabled = true;
+ }
+ }
+ catch(NumberFormatException e)
+ {
+ log.error("Can't enable Oracle's statement caching, illegal value for attribute: "
+ + ATTRIBUTE_STATEMENT_CACHE_SIZE + "=" + stmtCacheSize);
+ }
}
- catch (Exception e)
+ if(!enabled)
{
- if (logger.isDebugEnabled())
+ oraStatementCachingAvailable = false;
+ log.info("Oracle's statement caching not used: "+ ATTRIBUTE_STATEMENT_CACHE_SIZE + "=" + stmtCacheSize);
+ }
+ else
+ {
+ log.info("Prepared to use Oracle's statement caching: "+ ATTRIBUTE_STATEMENT_CACHE_SIZE + "=" + stmtCacheSize);
+ }
+ }
+
+ if(oraRowPrefetchAvailable)
+ {
+ String prefetchSize = jcd.getAttribute(ATTRIBUTE_PREFETCH_SIZE);
+ boolean enabled = false;
+ if(prefetchSize != null && prefetchSize.length() > 0)
+ {
+ try
+ {
+ Integer size = ConvertHelper.toInteger(prefetchSize);
+ if(size.intValue() > 0)
+ {
+ paramRowPrefetchSize = new Object[]{size};
+ enabled = true;
+ }
+ }
+ catch(NumberFormatException e)
{
- logger.debug("PlatformOracle9iImpl could not enable Oracle statement caching."
- + " Original/unwrapped connection classes="
- + connClass.getName() + "/" + oraConn.getClass().getName());
+ log.error("Can't enable Oracle's row prefetching, illegal value for attribute: "
+ + ATTRIBUTE_PREFETCH_SIZE + "=" + prefetchSize);
}
}
+ if(!enabled)
+ {
+ oraRowPrefetchAvailable = false;
+ log.info("Oracle's row prefetching not used: " + ATTRIBUTE_PREFETCH_SIZE + "=" + prefetchSize);
+ }
+ else
+ {
+ log.info("Prepared to use Oracle's row prefetching: " + ATTRIBUTE_PREFETCH_SIZE + "=" + prefetchSize);
+ }
}
- /*
- mkalen: Note from the Oracle documentation:
- Do not mix the JDBC 2.0 fetch size API and the Oracle row prefetching API
- in your application. You can use one or the other, but not both.
- */
- final ConnectionFactoryDescriptor cpd = jcd.getConnectionFactoryDescriptor();
- final int cpdFetchSizeHint = cpd.getFetchSize();
- if (cpdFetchSizeHint == 0 && ORA_ROW_PREFETCH_AVAILABLE)
+ String batchSize = jcd.getAttribute(ATTRIBUTE_BATCH_SIZE);
+ boolean enabled = false;
+ if(batchSize != null && batchSize.length() > 0)
{
try
{
- final String prefetchFromJcd;
- prefetchFromJcd = cpd.getJdbcProperties().getProperty("defaultRowPrefetch");
- if (prefetchFromJcd == null)
+ Integer size = ConvertHelper.toInteger(batchSize);
+ if(size.intValue() > 0)
{
- METHOD_SET_ROW_PREFETCH.invoke(oraConn, PARAM_ROW_PREFETCH_SIZE);
+ paramStatementBatchSize = new Object[]{size};
+ enabled = true;
}
- // Else, number of prefetched rows were set via Properties on Connection
}
- catch (Exception e)
+ catch(NumberFormatException e)
{
- if (logger.isDebugEnabled())
+ log.error("Can't enable Oracle's native batching, illegal value for attribute: "
+ + ATTRIBUTE_BATCH_SIZE + "=" + batchSize);
+ }
+ }
+ if(!enabled)
+ {
+ oraBatchAvailable = false;
+ log.info("Oracle's native batching not used: " + ATTRIBUTE_BATCH_SIZE + "=" + batchSize);
+ }
+ else
+ {
+ log.info("Prepared to use Oracle's native batching: " + ATTRIBUTE_BATCH_SIZE + "=" + batchSize);
+ }
+ }
+
+ /**
+ * Enables Oracle statement caching and row prefetching if supported by the JDBC-driver.
+ * @param conn the <code>Connection</code>-object (physical) to be initialized
+ * @see PlatformDefaultImpl#initializeJdbcConnection
+ * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html">
+ * Oracle TechNet Statement Caching Sample</a>
+ * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html">
+ * Oracle TechNet Row Pre-fetch Sample<a>
+ */
+ public void initializeJdbcConnection(final Connection conn) throws PlatformException
+ {
+ // Do all the generic initialization in PlatformDefaultImpl first
+ super.initializeJdbcConnection(conn);
+
+ Connection oraConn = null;
+ if(oraStatementCachingAvailable || oraRowPrefetchAvailable)
+ {
+ oraConn = unwrapConnection(conn);
+ }
+ if(oraConn != null)
+ {
+ final Class connClass = conn.getClass();
+ if(oraRowPrefetchAvailable)
+ {
+ /*
+ mkalen: Note from the Oracle documentation:
+ Do not mix the JDBC 2.0 fetch size API and the Oracle row prefetching API
+ in your application. You can use one or the other, but not both.
+ */
+ final ConnectionFactoryDescriptor cpd = jcd.getConnectionFactoryDescriptor();
+ if (cpd.getFetchSize() == 0)
+ {
+ try
+ {
+ final String prefetchFromJcd = cpd.getJdbcProperties().getProperty("defaultRowPrefetch");
+ if (prefetchFromJcd == null)
+ {
+ METHOD_SET_ROW_PREFETCH.invoke(oraConn, paramRowPrefetchSize);
+ if(log.isDebugEnabled()) log.debug("Oracle's native row prefetching enabled for connection " + conn);
+ }
+ // Else, number of prefetched rows were set via Properties on Connection
+ }
+ catch (Exception e)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("PlatformOracle9iImpl could not enable Oracle row pre-fetching."
+ + "Original/unwrapped connection classes="
+ + connClass.getName() + "/" + oraConn.getClass().getName(), e);
+ }
+ }
+ }
+ }
+ if(oraStatementCachingAvailable)
+ {
+ // At this point we know that we have an OracleConnection instance and can thus
+ // try to invoke methods via reflection (if available)
+ try
+ {
+ // Set number of cached statements and enable implicit caching
+ METHOD_SET_STATEMENT_CACHE_SIZE.invoke(oraConn, paramStatementCacheSize);
+ METHOD_SET_IMPLICIT_CACHING_ENABLED.invoke(oraConn, PARAM_BOOLEAN_TRUE);
+ if(log.isDebugEnabled())
+ {
+ log.debug("Oracle's native implicit statement caching enabled for connection " + conn);
+ }
+ }
+ catch (Exception e)
{
- logger.debug("PlatformOracle9iImpl could not enable Oracle row pre-fetching."
- + "Original/unwrapped connection classes="
- + connClass.getName() + "/" + oraConn.getClass().getName());
+ if (log.isDebugEnabled())
+ {
+ log.debug("PlatformOracle9iImpl could not enable Oracle statement caching."
+ + " Original/unwrapped connection classes="
+ + connClass.getName() + "/" + oraConn.getClass().getName());
+ }
}
}
}
+ else
+ {
+ if(log.isDebugEnabled())
+ {
+ log.debug("Can't unwrap connection, statement caching and row prefetching can't be used");
+ }
+ }
}
/**
@@ -248,24 +423,29 @@
*/
public void beforeBatch(PreparedStatement stmt) throws PlatformException
{
- // Check for Oracle batching support
- final Method methodSetExecuteBatch;
- final Method methodSendBatch;
- methodSetExecuteBatch = ClassHelper.getMethod(stmt, "setExecuteBatch", PARAM_TYPE_INTEGER);
- methodSendBatch = ClassHelper.getMethod(stmt, "sendBatch", null);
-
- final boolean statementBatchingSupported = methodSetExecuteBatch != null && methodSendBatch != null;
- if (statementBatchingSupported)
+ if (oraBatchAvailable)
{
- try
+ // Check for Oracle batching support
+ final Method methodSetExecuteBatch;
+ final Method methodSendBatch;
+ methodSetExecuteBatch = ClassHelper.getMethod(stmt, "setExecuteBatch", PARAM_TYPE_INTEGER);
+ methodSendBatch = ClassHelper.getMethod(stmt, "sendBatch", null);
+ if(methodSetExecuteBatch != null && methodSendBatch != null)
{
- // Set number of statements per batch
- methodSetExecuteBatch.invoke(stmt, PARAM_STATEMENT_BATCH_SIZE);
- m_batchStatementsInProgress.put(stmt, methodSendBatch);
+ try
+ {
+ // Set number of statements per batch
+ methodSetExecuteBatch.invoke(stmt, paramStatementBatchSize);
+ m_batchStatementsInProgress.put(stmt, methodSendBatch);
+ }
+ catch (Exception e)
+ {
+ throw new PlatformException(e.getLocalizedMessage(), e);
+ }
}
- catch (Exception e)
+ else
{
- throw new PlatformException(e.getLocalizedMessage(), e);
+ super.beforeBatch(stmt);
}
}
else
@@ -283,8 +463,7 @@
public void addBatch(PreparedStatement stmt) throws PlatformException
{
// Check for Oracle batching support
- final boolean statementBatchingSupported = m_batchStatementsInProgress.containsKey(stmt);
- if (statementBatchingSupported)
+ if (m_batchStatementsInProgress.containsKey(stmt))
{
try
{
@@ -327,6 +506,8 @@
}
catch (Exception e)
{
+ log.error("Error when invoke batch statement", e);
+ e = (Exception) ExceptionUtils.getRootCause(e);
throw new PlatformException(e.getLocalizedMessage(), e);
}
}
@@ -348,9 +529,7 @@
{
oraStmt = unwrapStatement(ps);
oraConn = unwrapConnection(ps.getConnection());
- oraLargeLobSupportAvailable =
- oraStmt != null && oraConn != null &&
- (sqlType == Types.CLOB ? ORA_CLOB_HANDLING_AVAILABLE : ORA_BLOB_HANDLING_AVAILABLE);
+ oraLargeLobSupportAvailable = oraStmt != null && oraConn != null && oraLobHandlingAvailable;
}
else
{
@@ -367,20 +546,6 @@
super.changePreparedStatementResultSetType(ps);
ps.setBinaryStream(index, inputStream, buf.length);
}
- else if (value instanceof Double)
- {
- // workaround for the bug in Oracle thin driver
- ps.setDouble(index, ((Double) value).doubleValue());
- }
- else if (sqlType == Types.BIGINT && value instanceof Integer)
- {
- // workaround: Oracle thin driver problem when expecting long
- ps.setLong(index, ((Integer) value).intValue());
- }
- else if (sqlType == Types.INTEGER && value instanceof Long)
- {
- ps.setLong(index, ((Long) value).longValue());
- }
else if (sqlType == Types.CLOB && oraLargeLobSupportAvailable && value instanceof String)
{
// TODO: If using Oracle update batching with the thin driver, throw exception on 4k limit
@@ -429,20 +594,24 @@
* @param conn the connection to unwrap (if needed)
* @return OracleConnection or null if not able to unwrap
*/
- protected Connection unwrapConnection(Connection conn)
+ protected Connection unwrapConnection(final Connection conn)
{
- final Connection unwrapped = unwrapHelper.unwrapConnection(ORA_CONN_CLASS, conn);
- if (unwrapped == null)
+ Connection result = conn;
+ if(conn != null)
{
- // mkalen: only log this as debug since it will be logged for every connection
- // (ie only useful during development).
- if (logger.isDebugEnabled())
+ result = unwrapHelper.unwrapConnection(ORA_CONN_CLASS, conn);
+ if (result == null)
{
- logger.debug("PlatformOracle9iImpl could not unwrap " + conn.getClass().getName() +
- ", Oracle-extensions disabled.");
+ // mkalen: only log this as debug since it will be logged for every connection
+ // (ie only useful during development).
+ if (log.isDebugEnabled())
+ {
+ log.debug("PlatformOracle9iImpl could not unwrap connection: " + conn.getClass() +
+ ", can't use Oracle's native Connection extensions.");
+ }
}
}
- return unwrapped;
+ return result;
}
/**
@@ -450,81 +619,23 @@
* @param ps the PreparedStatement to unwrap (if needed)
* @return OraclePreparedStatement or null if not able to unwrap
*/
- protected Statement unwrapStatement(Statement ps)
+ protected Statement unwrapStatement(final Statement ps)
{
- final Statement unwrapped = unwrapHelper.unwrapStatement(ORA_PS_CLASS, ps);
- if (unwrapped == null)
+ Statement result = ps;
+ if(ps != null)
{
- // mkalen: only log this as debug since it will be logged for every connection
- // (ie only useful during development).
- if (logger.isDebugEnabled())
+ result = unwrapHelper.unwrapStatement(ORA_PS_CLASS, ps);
+ if (result == null)
{
- logger.debug("PlatformOracle9iImpl could not unwrap " + ps.getClass().getName() +
- ", large CLOB/BLOB support disabled.");
+ // mkalen: only log this as debug since it will be logged for every connection
+ // (ie only useful during development).
+ if (log.isDebugEnabled())
+ {
+ log.debug("PlatformOracle9iImpl could not unwrap statement: " + ps.getClass() +
+ ", can't use Oracle's native Statement extensions.");
+ }
}
}
- return unwrapped;
+ return result;
}
-
- /**
- * Initializes static variables needed for Oracle-extensions and large BLOB/CLOB support.
- */
- protected void initOracleReflectedVars()
- {
- super.initOracleReflectedVars();
- try
- {
- /*
- Check for Oracle-specific classes, OracleConnection-specific
- statement caching/row pre-fetch methods and Oracle BLOB/CLOB access methods.
- We can do this in constructor in spite of possible mixing of instance being
- able vs unable passed at runtime (since withouth these classes and methods
- it's impossible to enable ORA-extensions at all even if instances are capable).
- */
- ORA_CONN_CLASS = ClassHelper.getClass("oracle.jdbc.OracleConnection", false);
- ORA_PS_CLASS = ClassHelper.getClass("oracle.jdbc.OraclePreparedStatement", false);
- ORA_CLOB_CLASS = ClassHelper.getClass("oracle.sql.CLOB", false);
- ORA_BLOB_CLASS = ClassHelper.getClass("oracle.sql.BLOB", false);
- PARAM_TYPE_INT_ORACLOB = new Class[]{ Integer.TYPE, ORA_CLOB_CLASS };
- PARAM_TYPE_INT_ORABLOB = new Class[]{ Integer.TYPE, ORA_BLOB_CLASS };
-
- /*
- The unwrap pattern used in {@link org.apache.ojb.broker.util.UnwrapHelper}
- to unwrap connection instance to Oracle's specific connection implementation class.
- */
- Object[] oracleUnwrapPattern = new Object[] {"oracle 10g", UnwrapHelper.TYPE_METHOD,
- new Class[]{ORA_CONN_CLASS}, "unwrapCompletely", null, null, null};
- unwrapHelper = new UnwrapHelper();
- // add the oracle unwrap pattern
- unwrapHelper.addUnwrapPattern(oracleUnwrapPattern);
-
- METHOD_SET_STATEMENT_CACHE_SIZE =
- ClassHelper.getMethod(ORA_CONN_CLASS, "setStatementCacheSize", PARAM_TYPE_INTEGER);
- METHOD_SET_IMPLICIT_CACHING_ENABLED =
- ClassHelper.getMethod(ORA_CONN_CLASS, "setImplicitCachingEnabled", PARAM_TYPE_BOOLEAN);
- METHOD_SET_ROW_PREFETCH = ClassHelper.getMethod(ORA_CONN_CLASS, "setDefaultRowPrefetch", PARAM_TYPE_INTEGER);
- METHOD_SET_CLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setCLOB", PARAM_TYPE_INT_ORACLOB);
- METHOD_SET_BLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setBLOB", PARAM_TYPE_INT_ORABLOB);
-
- ORA_STATEMENT_CACHING_AVAILABLE =
- METHOD_SET_STATEMENT_CACHE_SIZE != null && METHOD_SET_IMPLICIT_CACHING_ENABLED != null;
- ORA_ROW_PREFETCH_AVAILABLE = METHOD_SET_ROW_PREFETCH != null;
- ORA_CLOB_HANDLING_AVAILABLE = METHOD_SET_CLOB != null;
- ORA_BLOB_HANDLING_AVAILABLE = METHOD_SET_BLOB != null;
- }
- catch (ClassNotFoundException e)
- {
- // ignore (we tried...)
- }
- // Isolated checks for other connection classes (OK when not found)
- try
- {
- JBOSS_CONN_CLASS = ClassHelper.getClass(JBOSS_CONN_NAME, false);
- }
- catch (ClassNotFoundException e)
- {
- // ignore (no problem)
- }
- }
-
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java Fri Jan 12 10:19:39 2007
@@ -18,22 +18,27 @@
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.io.Serializable;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
-import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Properties;
+import org.apache.commons.lang.SerializationUtils;
+import org.apache.ojb.broker.PersistenceBrokerSQLException;
+import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+import org.apache.ojb.broker.util.ClassHelper;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
-import org.apache.ojb.broker.util.ClassHelper;
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
/**
@@ -120,44 +125,50 @@
* </tr>
* </table>
*
- * @author <a href="mailto:[email protected]">Thomas Mahler <a>
- * @author <a href="mailto:[email protected]">Martin Kalén</a>
* @version $Id$
*/
public class PlatformOracleImpl extends PlatformDefaultImpl
{
- 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";
+ protected static final String THIN_URL_PREFIX = "jdbc:oracle:thin";
/**
* Field value of <code>oracle.jdbc.OracleTypes.CURSOR</code>.
* @see #initOracleReflectedVars
*/
- protected static int ORACLE_JDBC_TYPE_CURSOR = -10;
+ protected int ORACLE_JDBC_TYPE_CURSOR = -10;
private Logger logger = LoggerFactory.getLogger(PlatformOracleImpl.class);
- private Boolean usingOracleOCIDriver;
+ public PlatformOracleImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ initOracleReflectedVars();
+ }
/**
- * Default constructor.
+ * Initializes static variables needed for getting Oracle-specific JDBC types.
*/
- public PlatformOracleImpl()
+ private void initOracleReflectedVars()
{
- initOracleReflectedVars();
+ try
+ {
+ // Check for Oracle-specific Types class
+ final Class oracleTypes = ClassHelper.getClass("oracle.jdbc.OracleTypes", false);
+ final Field cursorField = oracleTypes.getField("CURSOR");
+ ORACLE_JDBC_TYPE_CURSOR = cursorField.getInt(null);
+ }
+ catch (ClassNotFoundException e)
+ {
+ log.warn("PlatformOracleImpl could not find Oracle JDBC classes");
+ }
+ catch (NoSuchFieldException e)
+ {
+ log.warn("PlatformOracleImpl could not find Oracle JDBC type fields");
+ }
+ catch (IllegalAccessException e)
+ {
+ log.warn("PlatformOracleImpl could not get Oracle JDBC type values");
+ }
}
/**
@@ -208,26 +219,16 @@
public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType)
throws SQLException
{
- if (((sqlType == Types.VARBINARY) || (sqlType == Types.LONGVARBINARY) || (sqlType == Types.BLOB))
- && (value instanceof byte[]))
+ if ((sqlType == Types.VARCHAR || sqlType == Types.CHAR) && (value instanceof String || value instanceof Character))
{
- byte buf[] = (byte[]) value;
- int length = buf.length;
- if (!isUsingOracleOCIDriver(ps.getConnection()) && length > NON_OCI_BLOB_MAX_SIZE)
- {
- 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);
- ps.setBinaryStream(index, inputStream, length);
+ if (value instanceof String)
+ {
+ ps.setString(index, (String) value);
+ }
+ else // assert: value instanceof Character
+ {
+ ps.setString(index, value.toString());
+ }
}
else if (value instanceof Double)
{
@@ -265,36 +266,55 @@
reader = new InputStreamReader(inputStream);
length = buf.length;
}
- if (!isUsingOracleOCIDriver(ps.getConnection()) && length > NON_OCI_CLOB_MAX_SIZE)
- {
- 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);
}
- else if ((sqlType == Types.CHAR || sqlType == Types.VARCHAR)
- &&
- (value instanceof String || value instanceof Character))
+ else if ((value instanceof byte[]) && ((sqlType == Types.VARBINARY) || (sqlType == Types.LONGVARBINARY) || (sqlType == Types.BLOB)))
{
- if (value instanceof String)
+// byte buf[] = (byte[]) value;
+// int length = buf.length;
+// ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
+// // arminw: seems this no longer mandatory
+// //changePreparedStatementResultSetType(ps);
+// ps.setBinaryStream(index, inputStream, length);
+ ps.setBytes(index, (byte[]) value);
+ }
+ else if(sqlType == Types.JAVA_OBJECT)
+ {
+ // JAVA_OBJECT is not proper supported, workaround: use BLOB type
+ byte[] ser = SerializationUtils.serialize((Serializable) value);
+ ps.setBytes(index, ser);
+ }
+ else
+ {
+ super.setObjectForStatement(ps, index, value, sqlType);
+ }
+ }
+
+ public Object postPrepareReadInValue(final FieldDescriptor fld, final Object value)
+ {
+ /*
+ workaround for JAVA_OBJECT type. Currently Oracle doesn't
+ proper support JAVA_OBJECT type. On insert we transform JAVA_OBJECT
+ to byte[] array, thus on read we have to deserialize. The mapping type
+ is BLOB.
+ */
+ if(fld.getJdbcType().getType() == Types.JAVA_OBJECT && value instanceof Blob)
+ {
+ Blob ret = (Blob) value;
+ byte[] b;
+ try
{
- ps.setString(index, (String) value);
+ b = ret.getBytes(1, (int) ret.length());
}
- else // assert: value instanceof Character
+ catch(SQLException e)
{
- ps.setString(index, value.toString());
+ throw new PersistenceBrokerSQLException("Can't read Blob object of serialized JAVA_OBJECT type", e);
}
+ return SerializationUtils.deserialize(b);
}
else
{
- super.setObjectForStatement(ps, index, value, sqlType);
+ return super.postPrepareReadInValue(fld, value);
}
}
@@ -332,6 +352,11 @@
return ORACLE_JOIN_SYNTAX;
}
+ public boolean supportsOrderByInSubSelect()
+ {
+ return false;
+ }
+
public String createSequenceQuery(String sequenceName)
{
return "CREATE SEQUENCE " + sequenceName;
@@ -421,78 +446,6 @@
throws SQLException
{
stmt.registerOutParameter(position, ORACLE_JDBC_TYPE_CURSOR);
- }
-
- /**
- * 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 String getDbUrl(Connection conn) {
- if (conn == null)
- {
- return "";
- }
- final DatabaseMetaData dbMetaData;
- final String dbUrl;
- try
- {
- dbMetaData = conn.getMetaData();
- dbUrl = dbMetaData.getURL();
- if (dbUrl != null)
- {
- return dbUrl;
- }
- }
- catch (Exception e)
- {
- // ignore it
- }
- 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 boolean isUsingOracleOCIDriver(Connection conn)
- {
- if(usingOracleOCIDriver == null)
- {
- final String dbUrl = getDbUrl(conn);
- usingOracleOCIDriver = (dbUrl != null && dbUrl.startsWith(OCI_URL_PREFIX)) ? Boolean.TRUE : Boolean.FALSE;
- }
- return usingOracleOCIDriver.booleanValue();
- }
-
- /**
- * Initializes static variables needed for getting Oracle-specific JDBC types.
- */
- protected void initOracleReflectedVars()
- {
- try
- {
- // Check for Oracle-specific Types class
- final Class oracleTypes = ClassHelper.getClass("oracle.jdbc.OracleTypes", false);
- final Field cursorField = oracleTypes.getField("CURSOR");
- ORACLE_JDBC_TYPE_CURSOR = cursorField.getInt(null);
- }
- catch (ClassNotFoundException e)
- {
- logger.warn("PlatformOracleImpl could not find Oracle JDBC classes");
- }
- catch (NoSuchFieldException e)
- {
- logger.warn("PlatformOracleImpl could not find Oracle JDBC type fields");
- }
- catch (IllegalAccessException e)
- {
- logger.warn("PlatformOracleImpl could not get Oracle JDBC type values");
- }
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformPostgreSQLImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformPostgreSQLImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformPostgreSQLImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformPostgreSQLImpl.java Fri Jan 12 10:19:39 2007
@@ -22,6 +22,7 @@
import org.apache.ojb.broker.query.LikeCriteria;
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific
@@ -113,6 +114,11 @@
public class PlatformPostgreSQLImpl extends PlatformDefaultImpl
{
+ public PlatformPostgreSQLImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType) throws SQLException
{
if ((value instanceof byte[]) && (sqlType == Types.LONGVARBINARY))
@@ -191,18 +197,18 @@
{
return "drop sequence " + sequenceName;
}
-
+
/* (non-Javadoc)
- * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
- */
+ * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
+ */
public void addPagingSql(StringBuffer anSqlString)
{
anSqlString.append(" LIMIT ? OFFSET ?");
}
-
+
/* (non-Javadoc)
- * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
- */
+ * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
+ */
public boolean supportsPaging()
{
return true;
@@ -225,7 +231,7 @@
*/
public String getEscapeClause(LikeCriteria aCriteria)
{
- if (LikeCriteria.getEscapeCharacter() != LikeCriteria.DEFAULT_ESCPAPE_CHARACTER)
+ if (LikeCriteria.getEscapeCharacter() != LikeCriteria.DEFAULT_ESCPAPE_CHARACTER)
{
// the default escape character is \, so there's no need for an escape clause
return super.getEscapeClause(aCriteria);
@@ -234,5 +240,5 @@
{
return "";
}
- }
+ }
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java Fri Jan 12 10:19:39 2007
@@ -23,6 +23,7 @@
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.commons.lang.SerializationUtils;
/**
@@ -112,6 +113,11 @@
*/
public class PlatformSapdbImpl extends PlatformDefaultImpl
{
+ public PlatformSapdbImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
public void setObjectForStatement(
PreparedStatement ps,
int index,
@@ -158,12 +164,15 @@
public byte getJoinSyntaxType()
{
return ORACLE_JOIN_SYNTAX;
+ //return SQL92_NOPAREN_JOIN_SYNTAX;
}
/**
* Override default ResultSet size determination (rs.last();rs.getRow())
- * with select count(*) operation
- * SAP db doesn't let you use the .last, .getRow() mechanism (.getRow() will return -1)
+ * with select count(*) operation. Older maxDB/sapDB driver doesn't let you
+ * use the .last, .getRow() mechanism (.getRow() will return -1). But the latest
+ * ones seem to work correctly. So make sure to use the latest drivers to
+ * get the correct results.
*/
public boolean useCountForResultsetSize()
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASAImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASAImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASAImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASAImpl.java Fri Jan 12 10:19:39 2007
@@ -35,6 +35,11 @@
*/
public class PlatformSybaseASAImpl extends PlatformSybaseImpl
{
+ public PlatformSybaseASAImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
/**
* Sybase Adaptive Server Enterprise (ASE) support timestamp to a precision of 1/300th of second.
* Adaptive Server Anywhere (ASA) support timestamp to a precision of 1/1000000tho of second.
@@ -47,7 +52,7 @@
public void initializeJdbcConnection(JdbcConnectionDescriptor jcd, Connection conn) throws PlatformException
{
// Do origial init
- super.initializeJdbcConnection(jcd, conn);
+ super.initializeJdbcConnection(conn);
// Execute a statement setting the tempory option
try
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASEImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASEImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASEImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseASEImpl.java Fri Jan 12 10:19:39 2007
@@ -1,5 +1,7 @@
package org.apache.ojb.broker.platforms;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+
/* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,6 +29,11 @@
*/
public class PlatformSybaseASEImpl extends PlatformSybaseImpl
{
+ public PlatformSybaseASEImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
public String getLastInsertIdentityQuery(String tableName)
{
// the function is used by the
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/platforms/PlatformSybaseImpl.java Fri Jan 12 10:19:39 2007
@@ -1,5 +1,7 @@
package org.apache.ojb.broker.platforms;
+import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+
/* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,6 +29,11 @@
*/
public class PlatformSybaseImpl extends PlatformDefaultImpl
{
+ public PlatformSybaseImpl(JdbcConnectionDescriptor jcd)
+ {
+ super(jcd);
+ }
+
/**
* Get join syntax type for this RDBMS - one on of the constants from JoinSyntaxType interface
*/
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/query/AbstractQueryImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/query/AbstractQueryImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/query/AbstractQueryImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/query/AbstractQueryImpl.java Fri Jan 12 10:19:39 2007
@@ -36,6 +36,8 @@
private Class m_searchClass;
private Class m_baseClass;
private boolean m_withExtents = true;
+ private boolean selectForUpdate;
+ private String postfix;
public AbstractQueryImpl()
{
@@ -132,14 +134,6 @@
{
m_searchClass = searchClass;
}
-
- /**
- * @see org.apache.ojb.broker.query.Query#preprocess(org.apache.ojb.broker.PersistenceBrokerInternal)
- */
- public void preprocess(PersistenceBrokerInternal aPb)
- {
- // do nothing
- }
public void setFetchSize(int fetchSize)
{
@@ -151,4 +145,31 @@
return fetchSize;
}
+ public boolean isSelectForUpdate()
+ {
+ return selectForUpdate;
+ }
+
+ public void setSelectForUpdate(boolean forUpdate)
+ {
+ this.selectForUpdate = forUpdate;
+ }
+
+ public String getQueryAffix()
+ {
+ return postfix;
+ }
+
+ public void setQueryAffix(String postfix)
+ {
+ this.postfix = postfix;
+ }
+
+ /**
+ * @see org.apache.ojb.broker.query.Query#preprocess(org.apache.ojb.broker.PersistenceBrokerInternal)
+ */
+ public void preprocess(PersistenceBrokerInternal aPb)
+ {
+ // do nothing
+ }
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/query/Query.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/query/Query.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/query/Query.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/query/Query.java Fri Jan 12 10:19:39 2007
@@ -46,7 +46,9 @@
*/
public interface Query extends Serializable
{
- static final long serialVersionUID = 7616997212439931319L; public static final int NO_START_AT_INDEX = 0;
+ static final long serialVersionUID = 7616997212439931319L;
+
+ public static final int NO_START_AT_INDEX = 0;
public static final int NO_END_AT_INDEX = 0;
public static final boolean SCROLLABLE = true;
public static final boolean NOT_SCROLLABLE = false;
@@ -93,14 +95,6 @@
* @param endAtIndex ending index, inclusive
*/
void setEndAtIndex(int endAtIndex);
-
-
- /**
- * Preprocess the Query using a PersistenceBroker.
- *
- * @param aPb the PersistenceBroker
- */
- public void preprocess(PersistenceBrokerInternal aPb);
/**
* @deprecated
@@ -109,7 +103,6 @@
void fullSize(int size);
/**
* @deprecated use OJBIterator.fullSize()
- * @return
*/
int fullSize();
@@ -117,8 +110,7 @@
boolean getWithExtents();
/**
- * Answer true if start- and endIndex is set
- * @return
+ * Answer true if start- and endIndex is set.
*/
public boolean usePaging();
@@ -136,5 +128,41 @@
* (or 0 if not set / using driver default)
*/
int getFetchSize();
+
+ /**
+ * Returns <em>true</em> if a "select .... for update" is enabled
+ * to lock the result set rows by the database.
+ */
+ boolean isSelectForUpdate();
+
+ /**
+ * Set <em>true</em> if a "select ... for update" database
+ * lock should be used (OJB will append the 'FOR UPDATE' expression
+ * at the end of the query string). By default it's disabled.
+ */
+ void setSelectForUpdate(boolean forUpdate);
+
+ /**
+ * Set an affix at the end of the query string.
+ *
+ * @param affix The affix string to append at the end of the query string.
+ */
+ void setQueryAffix(String affix);
+
+ /**
+ * Returns the affix string (By default no affix is set, so this method
+ * returns <em>null</em>).
+ *
+ * @return The query affix string or <em>null</em> if not set.
+ * @see #setQueryAffix(String)
+ */
+ String getQueryAffix();
+
+ /**
+ * Preprocess the Query using a PersistenceBroker.
+ *
+ * @param aPb the PersistenceBroker
+ */
+ public void preprocess(PersistenceBrokerInternal aPb);
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/query/QueryByIdentityImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/query/QueryByIdentityImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/query/QueryByIdentityImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/query/QueryByIdentityImpl.java Fri Jan 12 10:19:39 2007
@@ -92,4 +92,16 @@
{
return m_objectOrIdentity;
}
+
+ public void setQueryAffix(String postfix)
+ {
+ throw new UnsupportedOperationException(
+ "Method #setQueryAffix is not supported when using query objects of class ...ojb.broker.Identity");
+ }
+
+ public void setSelectForUpdate(boolean forUpdate)
+ {
+ throw new UnsupportedOperationException(
+ "Method #setSelectForUpdate is not supported when using query objects of class ...ojb.broker.Identity");
+ }
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/util/BrokerHelper.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/util/BrokerHelper.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/util/BrokerHelper.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/util/BrokerHelper.java Fri Jan 12 10:19:39 2007
@@ -30,7 +30,6 @@
import org.apache.commons.collections.iterators.ArrayIterator;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.ManageableCollection;
-import org.apache.ojb.broker.MtoNImplementor;
import org.apache.ojb.broker.OJB;
import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PBKey;
@@ -40,10 +39,12 @@
import org.apache.ojb.broker.core.PersistenceBrokerImpl;
import org.apache.ojb.broker.core.ValueContainer;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
+import org.apache.ojb.broker.core.proxy.ProxyFactory;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.FieldHelper;
+import org.apache.ojb.broker.metadata.IndirectionTableDescriptor;
import org.apache.ojb.broker.metadata.MetadataException;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
@@ -64,17 +65,18 @@
* Furthermore it was used to introduce new features related to {@link org.apache.ojb.broker.PersistenceBroker} - these
* new features and services (if they stand the test of time) will be moved to separate services in future.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public class BrokerHelper
{
public static final String REPOSITORY_NAME_SEPARATOR = "#";
private PersistenceBrokerImpl m_broker;
+ private ProxyFactory proxyFactory;
public BrokerHelper(PersistenceBrokerImpl broker)
{
this.m_broker = broker;
+ this.proxyFactory = broker.getProxyFactory();
}
/**
@@ -133,20 +135,21 @@
}
/**
- * Answer the real ClassDescriptor for anObj
- * ie. aCld may be an Interface of anObj, so the cld for anObj is returned
+ * Answer the real ClassDescriptor for realObject
+ * ie. aCld may be an Interface of the realObject, so
+ * the cld for realObject is returned.
*/
- private ClassDescriptor getRealClassDescriptor(ClassDescriptor aCld, Object anObj)
+ private ClassDescriptor getRealClassDescriptor(ClassDescriptor cld, Object realObject)
{
ClassDescriptor result;
- Class realClass = m_broker.getProxyFactory().getRealClass(anObj);
- if(aCld.getClassOfObject() == realClass)
+ Class realClass = proxyFactory.getRealClass(realObject);
+ if(cld.getClassOfObject().equals(realClass))
{
- result = aCld;
+ result = cld;
}
else
{
- result = aCld.getRepository().getDescriptorFor(realClass);
+ result = cld.getRepository().getDescriptorFor(realClass);
}
return result;
}
@@ -163,7 +166,7 @@
*/
public ValueContainer[] getKeyValues(ClassDescriptor cld, Object objectOrProxy, boolean convertToSql) throws PersistenceBrokerException
{
- IndirectionHandler handler = m_broker.getProxyFactory().getIndirectionHandler(objectOrProxy);
+ IndirectionHandler handler = proxyFactory.getIndirectionHandler(objectOrProxy);
if(handler != null)
{
@@ -172,19 +175,44 @@
else
{
ClassDescriptor realCld = getRealClassDescriptor(cld, objectOrProxy);
- return getValuesForObject(realCld.getPkFields(), objectOrProxy, convertToSql);
+ return getValues(realCld.getPkFields(), objectOrProxy, convertToSql);
}
}
/**
* Get the values of the fk-target-fields for an obj.
- * @param rds
- * @param objOrProxy
+ *
+ * @param rds The reference descriptor
+ * @param objOrProxy The object/proxy object.
* @throws PersistenceBrokerException
*/
public ValueContainer[] getFkTargetValuesForObject(ObjectReferenceDescriptor rds, Object objOrProxy, boolean convertToSql) throws PersistenceBrokerException
{
- Class refClass = m_broker.getProxyFactory().getRealClass(objOrProxy);
+ if(objOrProxy == null) throw new NullPointerException("Can't get FK target values from 'null' object");
+
+ Class refClass;
+ Object source = null;
+ IndirectionHandler handler = proxyFactory.getIndirectionHandler(objOrProxy);
+ if(handler != null)
+ {
+ if(handler.alreadyMaterialized())
+ {
+ source = handler.getRealSubject();
+ refClass = source.getClass();
+ }
+ else
+ {
+ refClass = handler.getIdentity().getObjectsRealClass();
+ }
+ }
+ else
+ {
+ source = objOrProxy;
+ // a object referenced by a super-reference-descriptor could never be a proxy object
+ // thus we only need to check this here
+ refClass = rds.isSuperReferenceDescriptor() ? rds.getItemClass() : objOrProxy.getClass();
+ }
+
ClassDescriptor refCld = m_broker.getClassDescriptor(refClass);
FieldDescriptor pkFd[] = refCld.getPkFields();
FieldDescriptor targetFd[] = rds.getForeignKeyTargetFieldDescriptors(refCld);
@@ -192,23 +220,34 @@
// use the values of the key-fields
if (targetFd.length == 0 || Arrays.equals(pkFd, targetFd))
{
- return getKeyValues(refCld, objOrProxy, convertToSql);
+ /*
+ arminw:
+ when using a 'super-reference' (specific 1:1 reference to enable "table per subclass"-inheritance) it's
+ important to use the pk-fields of the referenced class and not the pk-fields of the specified object
+ because when using 'super-references' the same object instance is used for base object and referenced
+ object. But we want the PK's defined in the super class, because the PK field can be overriden in
+ the sub-class, thus we have to "upcast" to fields of the super-class.
+ */
+ return source != null ?
+ getValues(pkFd, source, convertToSql)
+ : getKeyValues(refCld, handler.getIdentity(), convertToSql);
}
// use the values of the target-fields
- Object obj = m_broker.getProxyFactory().getRealObject(objOrProxy);
- return getValuesForObject(targetFd, obj, convertToSql);
+ Object obj = proxyFactory.getRealObject(objOrProxy);
+ return getValues(targetFd, obj, convertToSql);
}
/**
* Get the values of the fk-fields for an obj.
- * @param rds
- * @param objOrProxy
+ *
+ * @param rds The reference descriptor.
+ * @param objOrProxy The object/proxy object.
* @throws PersistenceBrokerException
*/
public ValueContainer[] getFkValuesForObject(ObjectReferenceDescriptor rds, Object objOrProxy, boolean convertToSql) throws PersistenceBrokerException
{
- Class refClass = m_broker.getProxyFactory().getRealClass(objOrProxy);
+ Class refClass = proxyFactory.getRealClass(objOrProxy);
ClassDescriptor refCld = m_broker.getClassDescriptor(refClass);
FieldDescriptor pkFd[] = refCld.getPkFields();
FieldDescriptor targetFd[] = rds.getForeignKeyFieldDescriptors(refCld);
@@ -220,21 +259,8 @@
}
// use the values of the target-fields
- Object obj = m_broker.getProxyFactory().getRealObject(objOrProxy);
- return getValuesForObject(targetFd, obj, convertToSql);
- }
-
- /**
- * Return primary key values of given Identity object.
- *
- * @param cld
- * @param oid
- * @return Object[]
- * @throws PersistenceBrokerException
- */
- public ValueContainer[] getKeyValues(ClassDescriptor cld, Identity oid) throws PersistenceBrokerException
- {
- return getKeyValues(cld, oid, true);
+ Object obj = proxyFactory.getRealObject(objOrProxy);
+ return getValues(targetFd, obj, convertToSql);
}
/**
@@ -273,20 +299,6 @@
}
/**
- * returns an Array with an Objects PK VALUES, with any java-to-sql
- * FieldConversion applied. If the Object is a Proxy or a VirtualProxy NO
- * conversion is necessary.
- *
- * @param objectOrProxy
- * @return Object[]
- * @throws PersistenceBrokerException
- */
- public ValueContainer[] getKeyValues(ClassDescriptor cld, Object objectOrProxy) throws PersistenceBrokerException
- {
- return getKeyValues(cld, objectOrProxy, true);
- }
-
- /**
* Decide if the given object value represents 'null'.
*/
public boolean representsNull(FieldDescriptor fld, Object aValue)
@@ -302,7 +314,7 @@
FieldDescriptor[] fields = cld.getPkFields();
boolean hasNull = false;
// an unmaterialized proxy object can never have nullified PK's
- IndirectionHandler handler = m_broker.getProxyFactory().getIndirectionHandler(obj);
+ IndirectionHandler handler = proxyFactory.getIndirectionHandler(obj);
if(handler == null || handler.alreadyMaterialized())
{
if(handler != null) obj = handler.getRealSubject();
@@ -318,6 +330,42 @@
}
/**
+ * Assign autoincrement field.
+ *
+ * @param target The target object.
+ * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the object or <em>null</em>.
+ * @param onlyNull If <em>true</em> only <em>null</em> fields will be incremented, else already populated
+ * fields will be reassigned with a new autoincrement value.
+ */
+ public void assignAutoIncrement(Object target, ClassDescriptor cld, boolean onlyNull)
+ {
+ if(cld == null)
+ {
+ cld = m_broker.getClassDescriptor(target.getClass());
+ }
+ FieldDescriptor[] flds = cld.getAutoIncrementFields();
+ for(int i = 0; i < flds.length; i++)
+ {
+ FieldDescriptor fld = flds[i];
+ if(onlyNull)
+ {
+ /*
+ setAutoIncrementValue returns a value that is
+ properly typed for the java-world. This value
+ needs to be converted to it's corresponding
+ sql type so that the entire result array contains
+ objects that are properly typed for sql.
+ */
+ if(representsNull(fld, fld.getPersistentField().get(target))) assignAutoIncrement(fld, target);
+ }
+ else
+ {
+ assignAutoIncrement(fld, target);
+ }
+ }
+ }
+
+ /**
* Set an autoincremented value in given object field that has already
* had a field conversion run on it, if an value for the given field is
* already set, it will be overridden - no further checks are done.
@@ -330,64 +378,48 @@
* @return the autoincremented value set on given object
* @throws PersistenceBrokerException if there is an erros accessing obj field values
*/
- private Object setAutoIncrementValue(FieldDescriptor fd, Object obj)
+ public Object assignAutoIncrement(FieldDescriptor fd, Object obj)
{
PersistentField f = fd.getPersistentField();
try
{
// lookup SeqMan for a value matching db column an
- Object result = m_broker.serviceSequenceManager().getUniqueValue(fd);
+ Object result = m_broker.serviceSequenceManager().getUniqueValue(m_broker, fd);
// reflect autoincrement value back into object
f.set(obj, result);
return result;
}
catch(MetadataException e)
{
- throw new PersistenceBrokerException(
- "Error while trying to autoincrement field " + f.getDeclaringClass() + "#" + f.getName(),
- e);
+ throw new PersistenceBrokerException("Error while trying to autoincrement field "
+ + f.getDeclaringClass() + "#" + f.getName(), e);
}
catch(SequenceManagerException e)
{
- throw new PersistenceBrokerException("Could not get key value", e);
+ throw new PersistenceBrokerException("Can't get autoincrement value", e);
}
}
-
+
/**
* Get the values of the fields for an obj.
- * Autoincrement values are automatically set.
- * @param fields
- * @param obj
- * @throws PersistenceBrokerException
- */
- public ValueContainer[] getValuesForObject(FieldDescriptor[] fields, Object obj, boolean convertToSql, boolean assignAutoincrement) throws PersistenceBrokerException
- {
- ValueContainer[] result = new ValueContainer[fields.length];
-
+ *
+ * @param fields The fields to extract values.
+ * @param obj The real (non-proxy) object.
+ * @param convertToSql If <em>true</em> all values are converted to sql-type.
+ * @return An array of extracted values.
+ */
+ public ValueContainer[] getValues(final FieldDescriptor[] fields,
+ final Object obj,
+ final boolean convertToSql) throws PersistenceBrokerException
+ {
+ final ValueContainer[] result = new ValueContainer[fields.length];
+ Object cv;
+ FieldDescriptor fd;
for(int i = 0; i < fields.length; i++)
{
- FieldDescriptor fd = fields[i];
- Object cv = fd.getPersistentField().get(obj);
+ fd = fields[i];
+ cv = fd.getPersistentField().get(obj);
- /*
- TODO: Separate this "voodoo stuff" in separate method, don't set autoincrement
- values in such intransparent manner.
- handle autoincrement attributes if
- - is a autoincrement field
- - field represents a 'null' value, is nullified
- and generate a new value
- */
- if(assignAutoincrement && fd.isAutoIncrement() && representsNull(fd, cv))
- {
- /*
- setAutoIncrementValue returns a value that is
- properly typed for the java-world. This value
- needs to be converted to it's corresponding
- sql type so that the entire result array contains
- objects that are properly typed for sql.
- */
- cv = setAutoIncrementValue(fd, obj);
- }
if(convertToSql)
{
// apply type and value conversion
@@ -399,11 +431,6 @@
return result;
}
- public ValueContainer[] getValuesForObject(FieldDescriptor[] fields, Object obj, boolean convertToSql) throws PersistenceBrokerException
- {
- return getValuesForObject(fields, obj, convertToSql, false);
- }
-
/**
* Returns an array containing values for all non PK field READ/WRITE attributes of the object
* based on the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
@@ -412,12 +439,12 @@
* the caller is reponsible to pass a valid descriptor.
*
* @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} to extract the RW-fields
- * @param obj The object with target fields to extract.
+ * @param obj The non-proxy object with target fields to extract.
* @throws MetadataException if there is an erros accessing obj field values
*/
public ValueContainer[] getNonKeyRwValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
{
- return getValuesForObject(cld.getNonPkRwFields(), obj, true);
+ return getValues(cld.getNonPkRwFields(), obj, true);
}
/**
@@ -433,7 +460,7 @@
*/
public ValueContainer[] getAllRwValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
{
- return getValuesForObject(cld.getAllRwFields(), obj, true);
+ return getValues(cld.getAllRwFields(), obj, true);
}
/**
@@ -485,12 +512,12 @@
* returns true if the primary key fields are valid for delete, else false.
* PK fields are valid if each of them contains a valid non-null value
* @param cld the ClassDescriptor
- * @param obj the object
+ * @param obj the object
* @return boolean
*/
public boolean assertValidPkForDelete(ClassDescriptor cld, Object obj)
{
- if(!m_broker.getProxyFactory().isProxy(obj))
+ if(!proxyFactory.isProxy(obj))
{
FieldDescriptor fieldDescriptors[] = cld.getPkFields();
int fieldDescriptorSize = fieldDescriptors.length;
@@ -508,10 +535,9 @@
}
/**
- * Build a Count-Query based on aQuery.
- *
- * @param aQuery The query to use.
- * @return The generated "count query".
+ * Build a Count-Query based on aQuery
+ * @param aQuery
+ * @return The count query
*/
public Query getCountQuery(Query aQuery)
{
@@ -633,7 +659,7 @@
countQuery.setPathOuterJoin(path);
}
}
-
+
//BRJ: add orderBy Columns asJoinAttributes
List orderBy = aQuery.getOrderBy();
if (orderBy != null && !orderBy.isEmpty())
@@ -643,8 +669,8 @@
{
joinAttributes[i] = ((FieldHelper)orderBy.get(i)).name;
}
-
- countQuery.setJoinAttributes(joinAttributes);
+
+ countQuery.setJoinAttributes(joinAttributes);
}
return countQuery;
@@ -742,7 +768,7 @@
{
linkOrUnlink(true, obj, ord, insert);
}
-
+
/**
* This method concatenate the main object and the specified reference
* object (1:1 reference a referenced object, 1:n and m:n reference a
@@ -775,7 +801,7 @@
*/
public boolean link(Object obj, String attributeName, Object reference, boolean insert)
{
- ClassDescriptor cld = m_broker.getDescriptorRepository().getDescriptorFor(m_broker.getProxyFactory().getRealClass(obj));
+ ClassDescriptor cld = m_broker.getDescriptorRepository().getDescriptorFor(proxyFactory.getRealClass(obj));
ObjectReferenceDescriptor ord;
boolean match = false;
// first look for reference then for collection
@@ -832,13 +858,13 @@
{
linkOrUnlink(false, obj, ord, insert);
}
-
+
private boolean linkOrUnlink(boolean doLink, Object obj, String attributeName, boolean insert)
{
boolean match = false;
- ClassDescriptor cld = m_broker.getDescriptorRepository().getDescriptorFor(m_broker.getProxyFactory().getRealClass(obj));
+ ClassDescriptor cld = m_broker.getDescriptorRepository().getDescriptorFor(proxyFactory.getRealClass(obj));
ObjectReferenceDescriptor ord;
-
+
// first look for reference then for collection
ord = cld.getObjectReferenceDescriptorByName(attributeName);
if (ord != null)
@@ -853,9 +879,9 @@
{
linkOrUnlinkXToMany(doLink, obj, cod, insert);
match = true;
- }
+ }
}
-
+
return match;
}
@@ -887,7 +913,7 @@
else
{
m_broker.unlinkXtoN(obj, cod);
- }
+ }
}
private void linkOrUnlinkOneToOne(boolean doLink, Object obj, ObjectReferenceDescriptor ord, boolean insert)
@@ -901,7 +927,7 @@
ClassDescriptor cld = ord.getClassDescriptor();
if(!cld.isMappedToTable())
{
- cld = m_broker.getDescriptorRepository().getDescriptorFor(m_broker.getProxyFactory().getRealClass(obj));
+ cld = m_broker.getDescriptorRepository().getDescriptorFor(proxyFactory.getRealClass(obj));
}
if (doLink)
@@ -942,11 +968,11 @@
{
if(cds.isMtoNRelation())
{
- m_broker.deleteMtoNImplementor(new MtoNImplementor(m_broker, cds, source, referenceToUnlink));
+ m_broker.mtoNBroker.deleteIndirectionTableEntry(cds.getIndirectionTableDescriptor(), source, referenceToUnlink);
}
else
{
- ClassDescriptor cld = m_broker.getClassDescriptor(m_broker.getProxyFactory().getRealClass(referenceToUnlink));
+ ClassDescriptor cld = m_broker.getClassDescriptor(proxyFactory.getRealClass(referenceToUnlink));
m_broker.unlinkFK(referenceToUnlink, cld, cds);
}
}
@@ -977,7 +1003,8 @@
{
if(cds.isMtoNRelation())
{
- m_broker.addMtoNImplementor(new MtoNImplementor(m_broker, cds, source, referenceToLink));
+ IndirectionTableDescriptor itd = cds.getIndirectionTableDescriptor();
+ m_broker.mtoNBroker.storeIndirectionTableEntry(itd, source, referenceToLink);
}
else
{
@@ -1088,24 +1115,24 @@
{
Query result = aQuery;
FieldDescriptor fd = aCld.getDiscriminatorField();
-
+
if (fd != null)
{
String discriminator = aCld.getDiscriminatorValue();
QueryByCriteria copyQuery = getQueryFactory().copyQuery(aQuery);
-
+
copyQuery.getCriteria().addColumnEqualTo(fd.getColumnName(), discriminator);
copyQuery.preprocess(aPb);
-
+
result = copyQuery;
}
-
+
return result;
}
/**
* Add a criteria for concrete classes to the copied query.<br>
- * use addEqualTo() if the list contains only 1 element, addIn() if it contains more elements
+ * use addEqualTo() if the list contains only 1 element, addIn() if it contains more elements
* @param aPb the broker
* @param aQuery
* @param cldinfo
@@ -1116,24 +1143,24 @@
Query result = aQuery;
List concreteClasses = cldinfo.concreteClasses;
FieldDescriptor fd = cldinfo.cld.getDiscriminatorField();
-
+
if (fd != null && concreteClasses != null && !concreteClasses.isEmpty())
{
QueryByCriteria copyQuery = getQueryFactory().copyQuery(aQuery);
-
+
if (concreteClasses.size() > 1)
{
copyQuery.getCriteria().addColumnIn(fd.getColumnName(), concreteClasses);
}
else
{
- copyQuery.getCriteria().addColumnEqualTo(fd.getColumnName(), concreteClasses.get(0));
+ copyQuery.getCriteria().addColumnEqualTo(fd.getColumnName(), concreteClasses.get(0));
}
-
+
copyQuery.preprocess(aPb);
- result = copyQuery;
+ result = copyQuery;
}
-
+
return result;
}
@@ -1146,12 +1173,12 @@
* the ClassDescriptor
*/
public ClassDescriptor cld;
-
+
/**
* a List of Strings
*/
- public List concreteClasses;
-
+ public List concreteClasses;
+
public String toString()
{
return cld.getFullTableName() + " " + concreteClasses;
@@ -1180,7 +1207,7 @@
}
/**
- * Build a Collection of CldInfos
+ * Build a Collection of CldInfos
* containing the classDescriptor and a collection of concreteClasses.
*/
private Collection buildCldInfos(Collection classDescriptors)
@@ -1237,9 +1264,10 @@
return result;
}
-
+
/**
- * returns an Array with an Objects CURRENT locking VALUES.
+ * Returns an Array with an Objects CURRENT locking VALUES.
+ *
* @param cld the ClassDescriptor
* @param obj the object to read the locking values from
* @throws PersistenceBrokerException if there is an erros accessing o field values
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.