Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManagerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManagerImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManagerImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManagerImpl.java Fri Jan 12 10:19:39 2007
@@ -31,11 +31,16 @@
import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.platforms.PlatformException;
import org.apache.ojb.broker.util.SqlHelper;
+import org.apache.ojb.broker.util.ExceptionHelper;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
/**
- * Manages the JDBC-Statement resources.
+ * Manages the JDBC-Statement resources. This class is responsible to create statements
+ * and to cleanup used resources like statements and result sets.
+ * <br/>
+ * Additionally this implementation supports a simple statement cache (without wrapping
+ * or "proxying" the used {@link java.sql.Connection} and {@link java.sql.Statement}).
*
* @version $Id$
*/
@@ -43,13 +48,17 @@
{
private Logger log = LoggerFactory.getLogger(StatementManagerImpl.class);
+ protected final static short STMT_TYPE_PREPARED = 2;
+ protected final static short STMT_TYPE_CALLABLE = 3;
+ protected final static short STMT_TYPE_NORMAL = 4;
+
/** the associated broker */
protected final PersistenceBrokerInternal broker;
protected final Platform platform;
protected final ConnectionManagerIF connectionManager;
/** force use of JDBC 1.0 statement creation */
- protected boolean FORCEJDBC1_0 = false;
+ protected boolean forceJdbc_1_0 = false;
/** Global fetch size, set in {@link org.apache.ojb.broker.metadata.ConnectionFactoryDescriptor}. */
protected final int fetchSize;
@@ -71,26 +80,34 @@
statementCache = new StatementBuffer(maxCachedStatements);
// detect JDBC level
double level = connectionManager.getConnectionDescriptor().getJdbcLevel();
- FORCEJDBC1_0 = level == 1.0;
+ forceJdbc_1_0 = level == 1.0;
}
public void closeResources(Statement stmt, ResultSet rs)
{
- Statement tmpStmt = stmt;
if(useStatementCache && statementCache.containsValue(stmt))
{
- tmpStmt = null;
+ // don't close the cached statement
+ internalCloseResources(null, rs);
+ }
+ else
+ {
+ internalCloseResources(stmt, rs);
}
+ }
+
+ void internalCloseResources(Statement stmt, ResultSet rs)
+ {
try
{
- platform.beforeStatementClose(tmpStmt, rs);
+ platform.beforeStatementClose(stmt, rs);
//close statement on wrapped statement class, or real statement
- if(tmpStmt != null)
+ if(stmt != null)
{
- if(log.isDebugEnabled()) log.debug("close used statement: " + tmpStmt);
- tmpStmt.close();
+ if(log.isDebugEnabled()) log.debug("close used statement: " + stmt);
+ stmt.close();
}
- platform.afterStatementClose(tmpStmt, rs);
+ platform.afterStatementClose(stmt, rs);
}
catch(PlatformException e)
{
@@ -105,6 +122,11 @@
public void beforeConnectionRelease()
{
+ clearStatementCache();
+ }
+
+ protected void clearStatementCache()
+ {
if(statementCache.size() > 0)
{
boolean old = useStatementCache;
@@ -115,7 +137,7 @@
while(it.hasNext())
{
it.next();
- closeResources((PreparedStatement) it.getValue(), null);
+ internalCloseResources((PreparedStatement) it.getValue(), null);
it.remove();
}
}
@@ -134,7 +156,11 @@
{
try
{
- return prepareStatement(connectionManager.getConnection(), sql, scrollable, callableStmt, explicitFetchSizeHint);
+ return (PreparedStatement) prepareStatement(
+ sql,
+ scrollable,
+ callableStmt ? STMT_TYPE_CALLABLE : STMT_TYPE_PREPARED,
+ explicitFetchSizeHint);
}
catch(SQLException ex)
{
@@ -156,14 +182,14 @@
}
/**
- * return a generic Statement for the given ClassDescriptor.
+ * Return a generic Statement for the given ClassDescriptor.
* Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
*/
public Statement getGenericStatement(boolean scrollable) throws PersistenceBrokerException
{
try
{
- return createStatement(connectionManager.getConnection(), scrollable,
+ return prepareStatement(null, scrollable, STMT_TYPE_NORMAL,
StatementManager.FETCH_SIZE_NOT_EXPLICITLY_SET);
}
catch(SQLException ex)
@@ -181,195 +207,155 @@
/**
* Prepares a statement with parameters that should work with most RDBMS.
*
- * @param con the connection to utilize
* @param sql the sql syntax to use when creating the statement.
* @param scrollable determines if the statement will be scrollable.
- * @param callableStmt if <code>false</code>, then a {@link java.sql.PreparedStatement}
- * will be created. If <code>true</code>, then a {@link java.sql.CallableStatement} will be created.
+ * @param stmtType The type of the statement, see {@link #STMT_TYPE_CALLABLE},
+ * {@link #STMT_TYPE_PREPARED}, {@link #STMT_TYPE_NORMAL}.
* @param explicitFetchSizeHint will be used as fetchSize hint
* (if applicable) if > 0
* @return a statement that can be used to execute the syntax contained in
* the <code>sql</code> argument.
*/
- protected PreparedStatement prepareStatement(Connection con,
- String sql,
+ protected Statement prepareStatement(String sql,
boolean scrollable,
- boolean callableStmt,
- int explicitFetchSizeHint) throws SQLException
+ short stmtType,
+ int explicitFetchSizeHint) throws SQLException, LookupException
{
- PreparedStatement result;
+ final Connection con = connectionManager.getConnection();
+ Statement result = null;
- if(useStatementCache && !callableStmt)
+ if(useStatementCache && stmtType != STMT_TYPE_NORMAL)
{
result = statementCache.getStatement(sql, scrollable, explicitFetchSizeHint);
- if(result != null)
+ if(result != null && !(result.getConnection() == con))
{
- return result;
+ result = null;
}
}
-
- // if a JDBC1.0 driver is used the signature
- // prepareStatement(String, int, int) is not defined.
- // we then call the JDBC1.0 variant prepareStatement(String)
- try
+ if(result == null)
{
- // if necessary use JDB1.0 methods
- if(!FORCEJDBC1_0)
+ // if a JDBC1.0 driver is used the signature
+ // prepareStatement(String, int, int) is not defined.
+ // we then call the JDBC1.0 variant prepareStatement(String)
+ try
{
- if(!callableStmt)
+ // if necessary use JDB1.0 methods
+ if(!forceJdbc_1_0)
{
- result =
- con.prepareStatement(
- sql,
- scrollable
- ? ResultSet.TYPE_SCROLL_INSENSITIVE
- : ResultSet.TYPE_FORWARD_ONLY,
- ResultSet.CONCUR_READ_ONLY);
- performFetchSizeSetting(result, explicitFetchSizeHint);
-
- // add statement to cache
- if(useStatementCache) statementCache.addStatement(sql, result, scrollable);
+ result = jdbcVersionTwoStatement(con, sql, scrollable, stmtType, explicitFetchSizeHint);
+ performFetchSizeSetting(result, explicitFetchSizeHint, sql);
}
else
{
- result =
- con.prepareCall(
- sql,
- scrollable
- ? ResultSet.TYPE_SCROLL_INSENSITIVE
- : ResultSet.TYPE_FORWARD_ONLY,
- ResultSet.CONCUR_READ_ONLY);
+ result = jdbcVersionOneStatement(con, sql, stmtType);
}
}
- else
+ catch(AbstractMethodError err)
{
- if(callableStmt)
+ // this exception is raised if Driver is not JDBC 2.0 compliant
+ log.warn("Used driver seems not JDBC 2.0 compatible, use the JDBC 1.0 mode", err);
+ result = jdbcVersionOneStatement(con, sql, stmtType);
+ forceJdbc_1_0 = true;
+ }
+ catch(SQLException eSql)
+ {
+ // there are JDBC Driver that nominally implement JDBC 2.0, but
+ // throw DriverNotCapableExceptions. If we catch one of these
+ // we force usage of JDBC 1.0
+ if(eSql
+ .getClass()
+ .getName()
+ .equals("interbase.interclient.DriverNotCapableException"))
{
- result = con.prepareStatement(sql);
-
- // add statement to cache
- if(useStatementCache) statementCache.addStatement(sql, result, scrollable);
+ log.warn("JDBC 2.0 problems with this interbase driver, we use the JDBC 1.0 mode");
+ result = jdbcVersionOneStatement(con, sql, stmtType);
+ forceJdbc_1_0 = true;
}
else
{
- result = con.prepareCall(sql);
+ throw eSql;
}
}
- }
- catch(AbstractMethodError err)
- {
- // this exception is raised if Driver is not JDBC 2.0 compliant
- log.warn("Used driver seems not JDBC 2.0 compatible, use the JDBC 1.0 mode", err);
- if(callableStmt)
- {
- result = con.prepareStatement(sql);
- }
- else
+ try
{
- result = con.prepareCall(sql);
+ platform.afterStatementCreate(result);
}
- FORCEJDBC1_0 = true;
- }
- catch(SQLException eSql)
- {
- // there are JDBC Driver that nominally implement JDBC 2.0, but
- // throw DriverNotCapableExceptions. If we catch one of these
- // we force usage of JDBC 1.0
- if(eSql
- .getClass()
- .getName()
- .equals("interbase.interclient.DriverNotCapableException"))
+ catch(PlatformException e)
{
- log.warn("JDBC 2.0 problems with this interbase driver, we use the JDBC 1.0 mode");
- if(callableStmt)
- {
- result = con.prepareStatement(sql);
- }
- else
- {
- result = con.prepareCall(sql);
- }
- FORCEJDBC1_0 = true;
- }
- else
- {
- throw eSql;
+ log.error("Platform dependend failure after create of new statement", e);
}
}
- try
- {
- platform.afterStatementCreate(result);
- }
- catch(PlatformException e)
- {
- log.error("Platform dependend failure", e);
- }
return result;
}
- /** Creates a statement with parameters that should work with most RDBMS. */
- protected Statement createStatement(Connection con, boolean scrollable, int explicitFetchSizeHint) throws SQLException
+ protected Statement jdbcVersionTwoStatement(final Connection con,
+ final String sql,
+ final boolean scrollable,
+ final short stmtType,
+ final int explicitFetchSizeHint) throws SQLException
{
- Statement result;
+ final Statement result;
try
{
- // if necessary use JDBC1.0 methods
- if(!FORCEJDBC1_0)
+ if(stmtType == STMT_TYPE_PREPARED)
{
- result =
- con.createStatement(
- scrollable
- ? ResultSet.TYPE_SCROLL_INSENSITIVE
- : ResultSet.TYPE_FORWARD_ONLY,
- ResultSet.CONCUR_READ_ONLY);
- performFetchSizeSetting(result, explicitFetchSizeHint);
+ result = con.prepareStatement( sql,
+ scrollable ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CONCUR_READ_ONLY);
+ performFetchSizeSetting(result, fetchSize, sql);
+ // add statement to cache
+ if(useStatementCache) statementCache.addStatement(sql, result, scrollable);
+ }
+ else if(stmtType == STMT_TYPE_CALLABLE)
+ {
+ result = con.prepareCall(sql,
+ scrollable ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CONCUR_READ_ONLY);
+ performFetchSizeSetting(result, fetchSize, sql);
+ // add statement to cache
+ if(useStatementCache) statementCache.addStatement(sql, result, scrollable);
}
else
{
- result = con.createStatement();
+ result = con.createStatement(
+ scrollable ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CONCUR_READ_ONLY);
}
}
- catch(AbstractMethodError err)
+ catch(SQLException e)
{
- // if a JDBC1.0 driver is used, the signature
- // createStatement(int, int) is not defined.
- // we then call the JDBC1.0 variant createStatement()
- log.warn("Used driver seems not JDBC 2.0 compatible, use the JDBC 1.0 mode", err);
- result = con.createStatement();
- FORCEJDBC1_0 = true;
+ String msg = ExceptionHelper.generateMessage("Statement creation failed", e, sql);
+ log.error(msg);
+ throw e;
}
- catch(SQLException eSql)
+ return result;
+ }
+
+ protected Statement jdbcVersionOneStatement(final Connection con,
+ final String sql,
+ final short stmtType) throws SQLException
+ {
+ final Statement result;
+ if(stmtType == STMT_TYPE_PREPARED)
{
- // there are JDBC Driver that nominally implement JDBC 2.0, but
- // throw DriverNotCapableExceptions. If we catch one of these
- // we force usage of JDBC 1.0
- if(eSql
- .getClass()
- .getName()
- .equals("interbase.interclient.DriverNotCapableException"))
- {
- log.warn("JDBC 2.0 problems with this interbase driver, we use the JDBC 1.0 mode");
- FORCEJDBC1_0 = true;
- result = con.createStatement();
- }
- else
- {
- throw eSql;
- }
+ result = con.prepareStatement(sql);
+ // add statement to cache
+ if(useStatementCache) statementCache.addStatement(sql, result, false);
}
- try
+ else if(stmtType == STMT_TYPE_CALLABLE)
{
- platform.afterStatementCreate(result);
+ result = con.prepareCall(sql);
+ // add statement to cache
+ if(useStatementCache) statementCache.addStatement(sql, result, false);
}
- catch(PlatformException e)
+ else
{
- log.error("Platform dependend failure", e);
+ result = con.createStatement();
}
return result;
}
- private void performFetchSizeSetting(Statement stmt, int explicitFetchSizeHint)
- throws SQLException
+ private void performFetchSizeSetting(final Statement stmt, final int explicitFetchSizeHint, final String sql)
{
if(stmt != null)
{
@@ -384,11 +370,22 @@
}
else
{
- fetchSizeHint = fetchSize; // connection pool default
+ fetchSizeHint = fetchSize; // configured default setting
}
- if(fetchSizeHint > 0)
+ try
{
- stmt.setFetchSize(fetchSize);
+ if(fetchSizeHint > 0)
+ {
+ stmt.setFetchSize(fetchSize);
+ }
+ else if(useStatementCache) // guarantee that cached stmt will use default fetch size setting
+ {
+ stmt.setFetchSize(StatementManager.FETCH_SIZE_NOT_EXPLICITLY_SET);
+ }
+ }
+ catch(SQLException e)
+ {
+ log.warn("Can't set fetch size '" + fetchSize + "' on statement for query: " + sql);
}
}
}
@@ -401,6 +398,15 @@
public void setUseStatementCache(boolean useStatementCache)
{
this.useStatementCache = useStatementCache;
+ if(!useStatementCache && statementCache.size() > 0)
+ {
+ clearStatementCache();
+ }
+ }
+
+ public Platform getPlatform()
+ {
+ return platform;
}
//===================================================================
@@ -415,27 +421,19 @@
super(max);
}
- void addStatement(String sql, PreparedStatement stmt, boolean scrollable)
+ void addStatement(String sql, Statement stmt, boolean scrollable)
{
// important to differ if the sql should be scrollable or not, thus
// append the result at the end of the sql key string
super.put(sql + BooleanUtils.toStringTrueFalse(scrollable), stmt);
}
- PreparedStatement getStatement(String sql, boolean scrollable, int fetchSize)
+ Statement getStatement(String sql, boolean scrollable, int fetchSize)
{
// important to differ if the sql should be scrollable or not, thus
// append the result at the end of the sql key string
- PreparedStatement result = (PreparedStatement) super.get(sql + BooleanUtils.toStringTrueFalse(scrollable));
- try
- {
- // allow to set fetch size for statement
- performFetchSizeSetting(result, fetchSize);
- }
- catch(SQLException e)
- {
- log.error("Can't set fetch size '" + fetchSize + "' on statement for query: " + sql);
- }
+ Statement result = (Statement) super.get(sql + BooleanUtils.toStringTrueFalse(scrollable));
+ performFetchSizeSetting(result, fetchSize, sql);
return result;
}
@@ -445,17 +443,8 @@
*/
protected boolean removeLRU(LinkEntry linkEntry)
{
- boolean old = useStatementCache;
- useStatementCache = false;
- try
- {
- closeResources((PreparedStatement) linkEntry.getValue(), null);
- return super.removeLRU(linkEntry);
- }
- finally
- {
- useStatementCache = old;
- }
+ internalCloseResources((Statement) linkEntry.getValue(), null);
+ return super.removeLRU(linkEntry);
}
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchListener.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchListener.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchListener.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchListener.java Fri Jan 12 10:19:39 2007
@@ -18,22 +18,21 @@
/**
* Makes possible to hock up in batch process.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public interface BatchListener
{
/**
- * Called before the {@link BatchEntity} was executed.
+ * Called before the {@link Batcher} was executed.
* @param entity The entity the {@link BatchManager} work on.
*/
- void beforeBatchExecution(BatchEntity entity);
+ void beforeBatchExecution(Batcher entity);
/**
- * Called after the {@link BatchEntity} was executed. If an exception occurs
+ * Called after the {@link Batcher} was executed. If an exception occurs
* while batch entry execution, this method will be skipped.
*
* @param entity The entity the {@link BatchManager} work on.
*/
- void afterBatchExecution(BatchEntity entity);
+ void afterBatchExecution(Batcher entity);
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManager.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManager.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManager.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManager.java Fri Jan 12 10:19:39 2007
@@ -31,24 +31,26 @@
/**
* Add values to batch.
*
- * @param info The metadata of the batch statement.
+ * @param batcher The batch metadata and values.
* @param values An array of {@link ValueContainer} representing the object
* or database row to batch.
* @param expectedResult The expected {@link java.sql.Statement} return
* value (number of modified rows).
* @throws SQLException
*/
- public void addToBatch(BatchInfo info, ValueContainer[] values, int expectedResult) throws SQLException;
+ public void add(Batcher batcher, ValueContainer[] values, int expectedResult) throws SQLException;
- /** Execute all hold out batch statements. */
+ /**
+ * Execute all hold out batch statements.
+ */
public void executeBatch() throws PersistenceBrokerException;
/**
- * Execute batch on given {@link BatchEntity}.
+ * Execute batch on given {@link Batcher}.
*
- * @param entity The {@link BatchEntity} to execute.
+ * @param batcher The {@link Batcher} to execute.
*/
- public void executeBatch(BatchEntity entity) throws PersistenceBrokerException;
+ public void executeBatch(Batcher batcher) throws PersistenceBrokerException;
/**
* Discard all batched statements and close all resources without
@@ -57,17 +59,13 @@
public void cancelBatch();
/**
- * Creates a new {@link BatchEntity} instance.
- *
- * @param descriptor An {@link BatchInfo} encapsulates meta info of the batch statement.
- * @return a new create batch entity.
+ * Add an {@link BatchListener} object.
*/
- public BatchEntity createEntity(BatchInfo descriptor);
-
- /** Add an {@link BatchListener} object. */
public void addBatchListener(BatchListener listener);
- /** Removes an {@link BatchListener} object. */
+ /**
+ * Removes an {@link BatchListener} object.
+ */
public void removeBatchListener(BatchListener listener);
/**
@@ -128,13 +126,19 @@
*/
public boolean getBatchSupportOptimisticLocking();
- /** Set the batch limit. */
+ /**
+ * Set the batch limit.
+ */
public void setBatchLimit(int limit);
- /** Get the batch limit. */
+ /**
+ * Get the batch limit.
+ */
public int getBatchLimit();
- /** Returns the used {@link BatchStrategy}. */
+ /**
+ * Returns the used {@link BatchStrategy}.
+ */
public BatchStrategy getStrategy();
/**
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManagerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManagerImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManagerImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchManagerImpl.java Fri Jan 12 10:19:39 2007
@@ -26,6 +26,7 @@
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.util.ExceptionHelper;
+import org.apache.ojb.broker.util.IdentityArrayList;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -42,7 +43,7 @@
* <td><strong>Property Values</strong></td>
* </tr>
* <tr>
- * <td>batch.includeOptimisticLocking</td>
+ * <td>batch.supportOptimisticLocking</td>
* <td>
* To support optimistic locking within batch mode the used jdbc-driver have to return
* the number of affected rows for each batched statement, see {@link java.sql.PreparedStatement#executeBatch()}.
@@ -57,7 +58,6 @@
* </tr>
* </table>
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public class BatchManagerImpl implements BatchManager
@@ -69,7 +69,6 @@
protected ReturnValueValidator validator;
private static final String BATCH_INCLUDE_OPTIMISTIC_LOCKING_PROPERTY_STR = "batch.supportOptimisticLocking";
- private static final BatchListener[] NULL_LISTENER = new BatchListener[0];
private int batchLimit = 50;
private int batchLimitCounter;
private boolean batchMode;
@@ -87,7 +86,10 @@
* can be set <em>true</em> to optimize the batch handling for objects with optimistic locking enabled.
*/
private boolean batchSupportOptimisticLocking;
- private BatchListener[] batchListener = NULL_LISTENER;
+ /**
+ * Object identity based list to register {@link BatchListener}.
+ */
+ private List batchListener = new IdentityArrayList();
private List batchEntities = new ArrayList();
public BatchManagerImpl(PersistenceBrokerInternal broker, ReturnValueValidator validator)
@@ -132,66 +134,20 @@
this.strategy = strategy;
}
- /** @see BatchManager#createEntity */
- public BatchEntity createEntity(BatchInfo descriptor)
- {
- return new BatchEntity(this, descriptor);
- }
-
- public void addToBatch(BatchInfo info, ValueContainer[] values, int expectedResult) throws SQLException
+ public void executeBatch(Batcher batcher)
{
- if(checkBatchLimit())
- {
- if(log.isEnabledFor(Logger.INFO))
- {
- log.info("Batch limit reached, execute batch before add new batch entry");
- }
- executeBatch();
- }
-
- BatchEntity entity = findEntity(info);
- if(entity == null)
- {
- // create new entity
- entity = new BatchEntity(this, info);
- if(log.isDebugEnabled()) log.debug("Create new BatchEntity: " + entity);
- // lookup batch strategy and ask for updated (reordered, reduced, ...)
- // list of batch entities
- batchEntities = strategy.prepareForBatch(batchEntities, entity);
- }
- if(log.isDebugEnabled()) log.debug("Add batch values " + ArrayUtils.toString(values));
- entity.addBatch(values, expectedResult);
- }
-
- private BatchEntity findEntity(BatchInfo info)
- {
- for(int i = 0; i < batchEntities.size(); i++)
- {
- BatchEntity batchEntity = (BatchEntity) batchEntities.get(i);
- if(batchEntity.getInfo().equals(info))
- {
- return batchEntity;
- }
- }
- return null;
- }
-
- /** @see BatchManager#executeBatch(BatchEntity) */
- public void executeBatch(BatchEntity entity)
- {
- if(log.isDebugEnabled()) log.debug("Execute BatchEntity performing "
- + entity.batchSize() + " batch entries. BatchEntity=" + entity);
- for(int i = 0; i < batchListener.length; i++)
+ if(log.isDebugEnabled()) log.debug("Execute Batcher performing "
+ + batcher.batchSize() + " batch entries. Batcher=" + batcher);
+ for(int i = 0; i < batchListener.size(); i++)
{
try
{
- batchListener[i].beforeBatchExecution(entity);
+ ((BatchListener) batchListener.get(i)).beforeBatchExecution(batcher);
}
catch(Exception e)
{
- log.error("BatchListener cause exception", e);
- throw new BatchException(
- "Error while perform batch listener before batch execution: " + batchListener[i]);
+ throw new BatchException("Error while perform batch listener before batch execution: "
+ + batchListener.get(i), e);
}
}
@@ -200,32 +156,31 @@
{
try
{
- result = entity.executeBatch();
+ result = batcher.executeBatch(broker.serviceStatementManager(), broker.serviceJdbcAccess());
Platform platform = broker.getConfiguration().getJdbcConnectionDescriptor().getPlatform();
- validator.validateResult(platform, entity.getInfo(), entity.getExpectedResults(), result);
+ validator.validateResult(platform, batcher, result);
}
finally
{
- entity.cleanup();
+ batcher.cleanup();
}
}
catch(SQLException e)
{
- BatchInfo info = entity.getInfo();
- throw ExceptionHelper.generateException(e, info.getSql(), info.getCld(), null, null, log);
+ throw ExceptionHelper.generateException(e, batcher.getSql(), batcher.getClassDescriptor(), null, null, log);
}
- for(int i = 0; i < batchListener.length; i++)
+ for(int i = 0; i < batchListener.size(); i++)
{
try
{
- batchListener[i].afterBatchExecution(entity);
+ ((BatchListener) batchListener.get(i)).afterBatchExecution(batcher);
}
catch(Exception e)
{
log.error("BatchListener cause exception", e);
throw new BatchException(
- "Error while perform batch listener after batch execution: " + batchListener[i]);
+ "Error while perform batch listener after batch execution: " + batchListener.get(i));
}
}
batchLimitCounter -= result.length;
@@ -236,24 +191,24 @@
{
if(batchEntities.size() == 0) return;
- if(log.isDebugEnabled()) log.debug("Excecute batch call on " + batchEntities.size() + " BatchEntity instances");
+ if(log.isDebugEnabled()) log.debug("Excecute batch call on " + batchEntities.size() + " Batcher instances");
try
{
Iterator it = batchEntities.iterator();
- BatchEntity entity;
+ Batcher batcher;
while(it.hasNext())
{
- entity = (BatchEntity) it.next();
- executeBatch(entity);
+ batcher = (Batcher) it.next();
+ executeBatch(batcher);
}
}
finally
{
- cancelBatch();
+ cleanupAndPrepare();
}
}
- public boolean checkBatchLimit()
+ public boolean batchLimitReached()
{
return batchLimitCounter > batchLimit;
}
@@ -261,49 +216,39 @@
/** @see BatchManager#cancelBatch */
public void cancelBatch()
{
+ cleanupAndPrepare();
+ }
+
+ /**
+ * Cleanup and prepare for reuse.
+ */
+ private void cleanupAndPrepare()
+ {
batchEntities.clear();
resetBatchCount();
}
public void addBatchListener(BatchListener listener)
{
- BatchListener[] newListeners = new BatchListener[batchListener.length + 1];
- System.arraycopy(batchListener, 0, newListeners, 0, batchListener.length);
- newListeners[newListeners.length - 1] = listener;
- batchListener = newListeners;
+ if(!batchListener.contains(listener))
+ {
+ batchListener.add(listener);
+ }
+ else
+ {
+ log.info("BatchListener add: Already added listener found, will ignore multiple listener add");
+ }
}
public void removeBatchListener(BatchListener listener)
{
- if(batchListener.length == 0) return;
-
- BatchListener[] newListeners = new BatchListener[batchListener.length - 1];
- int pos = 0;
- boolean match = false;
- for(int i = 0; i < batchListener.length; i++)
- {
- if(batchListener[i] != listener)
- {
- if(pos == batchListener.length)
- {
- // no listener match, break and don't change listener array
- log.info("Given BatchListener does not match, can't remove listener: " + listener);
- break;
- }
- newListeners[pos++] = batchListener[i];
- }
- else
- {
- match = true;
- }
- }
- if(match) batchListener = newListeners;
+ batchListener.remove(listener);
}
public void reset()
{
cancelBatch();
- batchListener = NULL_LISTENER;
+ batchListener.clear();
}
public void setBatchLimit(int limit)
@@ -348,7 +293,7 @@
}
/**
- * Was called by {@link BatchEntity} when a new set of values
+ * Was called by {@link Batcher} when a new set of values
* are added to batch.
*/
void increaseBatchCount()
@@ -359,5 +304,43 @@
private void resetBatchCount()
{
batchLimitCounter = 0;
+ }
+
+ public void add(Batcher batcher, ValueContainer[] values, int expectedResult) throws SQLException
+ {
+ if(batchLimitReached())
+ {
+ if(log.isEnabledFor(Logger.INFO))
+ {
+ log.info("Batch limit reached, execute batch before add new batch entry");
+ }
+ executeBatch();
+ }
+
+ Batcher entity = checkForExistingBatcher(batcher);
+ if(entity == null)
+ {
+ entity = batcher;
+ if(log.isDebugEnabled()) log.debug("Add new Batcher: " + batcher);
+ // lookup batch strategy and ask for updated (reordered, reduced, ...)
+ // list of batch entities
+ batchEntities = strategy.prepareForBatch(batchEntities, batcher);
+ }
+ if(log.isDebugEnabled()) log.debug("Add batch value row on batcher " + entity + ", values are "+ ArrayUtils.toString(values));
+ entity.add(values, expectedResult);
+ increaseBatchCount();
+ }
+
+ private Batcher checkForExistingBatcher(Batcher newBatcher)
+ {
+ for(int i = 0; i < batchEntities.size(); i++)
+ {
+ Batcher batcher = (Batcher) batchEntities.get(i);
+ if(batcher.equals(newBatcher))
+ {
+ return batcher;
+ }
+ }
+ return null;
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategy.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategy.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategy.java Fri Jan 12 10:19:39 2007
@@ -22,25 +22,24 @@
import org.apache.ojb.broker.OptimisticLockException;
/**
- * This class is reponsible for order of {@link BatchEntity} instances.
+ * This class is reponsible for order of {@link Batcher} instances.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public interface BatchStrategy
{
/**
- * Prepare the current enqueued {@link BatchEntity} objects for add of
+ * Prepare the current enqueued {@link Batcher} objects for add of
* the new entity - in general the strategy checks for conflicts with
- * the new entity and execute the batch
+ * the new entity and execute the batch.
*
- * @param entities A collection of already enqueued {@link BatchEntity} objects.
- * @param newEntity The new {@link BatchEntity} to add to batch queue.
+ * @param entities A collection of already enqueued {@link Batcher} objects.
+ * @param newEntity The new {@link Batcher} to add to batch queue.
* @return The new batch entity list <strong>including</strong> the new entity
- * (the order or/and the number of {@link BatchEntity} can be different from the orginal).
+ * (the order or/and the number of {@link Batcher} can be different from the orginal).
* @throws OptimisticLockException
*/
- List prepareForBatch(List entities, BatchEntity newEntity) throws OptimisticLockException;
+ List prepareForBatch(List entities, Batcher newEntity) throws OptimisticLockException;
/**
* Close this batch strategy.
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyBase.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyBase.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyBase.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyBase.java Fri Jan 12 10:19:39 2007
@@ -26,7 +26,6 @@
* {@link org.apache.ojb.broker.accesslayer.batch.BatchStrategyBase.TranspositionBan} interface to
* control the order of batch entries.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public abstract class BatchStrategyBase implements BatchStrategy
@@ -49,7 +48,7 @@
*/
public abstract TranspositionBan[] getTranspositionBans();
- public List prepareForBatch(List entities, BatchEntity newEntity) throws OptimisticLockException
+ public List prepareForBatch(List entities, Batcher newEntity) throws OptimisticLockException
{
/*
only new batch entity objects need to be checked.
@@ -73,27 +72,31 @@
CHECK_BANS_LOOP:
for(int i = entities.size() - 1; i >= 0; i--)
{
- BatchEntity next = (BatchEntity) entities.get(i);
+ Batcher next = (Batcher) entities.get(i);
for(int j = 0; j < bans.length; j++)
{
- if(bans[j].isBanned(newEntity.getInfo(), next.getInfo()))
+ if(bans[j].isBanned(newEntity, next))
{
toExecute = i + 1;
break CHECK_BANS_LOOP;
}
}
}
+ //System.out.println("*Batcher_before: " + entities.size());
if(toExecute > 0)
{
for(Iterator it = entities.iterator();
(toExecute > 0) && it.hasNext(); toExecute--)
{
- BatchEntity next = (BatchEntity) it.next();
+ Batcher next = (Batcher) it.next();
batchManager.executeBatch(next);
it.remove();
+ //System.out.println("*remove: " + next);
}
}
+ //System.out.println("*add: " + newEntity);
entities.add(newEntity);
+ //System.out.println("*Batcher_after: " + entities.size());
return entities;
}
@@ -105,10 +108,10 @@
/**
* Is transposition of batch entries of the given type banned?
*
- * @param infoNew The {@link BatchInfo} of the new or first batch entry.
- * @param infoOld The {@link BatchInfo} of the already buffered batch entry.
+ * @param batcher The {@link Batcher} of the new or first batch entry.
+ * @param batcherOther The {@link Batcher} of the already buffered batch entry.
* @return <em>True</em> if transposition is banned.
*/
- public boolean isBanned(BatchInfo infoNew, BatchInfo infoOld);
+ public boolean isBanned(Batcher batcher, Batcher batcherOther);
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyDefaultImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyDefaultImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyDefaultImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/BatchStrategyDefaultImpl.java Fri Jan 12 10:19:39 2007
@@ -27,16 +27,15 @@
* follows from the known relations between tables,
* reflected in repository.xml.
*
- * @author <a href="mailto:[email protected]">Oleg Nitz</a>
* @version $Id$
*/
public class BatchStrategyDefaultImpl extends BatchStrategyBase
{
private TranspositionBan[] bans = new TranspositionBan[]{
- new InsertTranspositionBan(),
- new DeleteTranspositionBan(),
- new TheSameTableTranspositionBan(),
+ new InsertTranspositionBan(),
+ new DeleteTranspositionBan(),
+ new TheSameTableTranspositionBan(),
};
public BatchStrategyDefaultImpl(BatchManager batchManager)
@@ -55,18 +54,17 @@
/**
* Does cld1 have reference to cld2?
*/
- private boolean hasReferenceTo(BatchInfo infoNew, BatchInfo infoOld)
+ private boolean hasReferenceTo(Batcher infoNew, Batcher infoOld)
{
- if(infoNew.getCld() != null && infoOld.getCld() != null)
+ if(infoNew.getClassDescriptor() != null && infoOld.getClassDescriptor() != null)
{
- List ordList = infoNew.getCld().getObjectReferenceDescriptors();
+ List ordList = infoNew.getClassDescriptor().getObjectReferenceDescriptors();
if(!ordList.isEmpty())
{
- Class class2 = infoOld.getCld().getClassOfObject();
+ Class class2 = infoOld.getClassDescriptor().getClassOfObject();
for(Iterator it = ordList.iterator(); it.hasNext();)
{
- ObjectReferenceDescriptor ord =
- (ObjectReferenceDescriptor) it.next();
+ ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) it.next();
if(ord.getItemClass().isAssignableFrom(class2))
{
return true;
@@ -80,20 +78,18 @@
/**
* Does cld1 have collection of cld2?
*/
- private boolean hasCollection1ToNOf(BatchInfo infoNew, BatchInfo infoOld)
+ private boolean hasCollection1ToNOf(Batcher infoNew, Batcher infoOld)
{
- if(infoNew.getCld() != null && infoOld.getCld() != null)
+ if(infoNew.getClassDescriptor() != null && infoOld.getClassDescriptor() != null)
{
- List codList = infoNew.getCld().getCollectionDescriptors();
+ List codList = infoNew.getClassDescriptor().getCollectionDescriptors();
if(!codList.isEmpty())
{
- Class class2 = infoOld.getCld().getClassOfObject();
+ Class class2 = infoOld.getClassDescriptor().getClassOfObject();
for(Iterator it2 = codList.iterator(); it2.hasNext();)
{
- CollectionDescriptor cod =
- (CollectionDescriptor) it2.next();
- if(!cod.isMtoNRelation()
- && cod.getItemClass().isAssignableFrom(class2))
+ CollectionDescriptor cod = (CollectionDescriptor) it2.next();
+ if(!cod.isMtoNRelation() && cod.getItemClass().isAssignableFrom(class2))
{
return true;
}
@@ -103,6 +99,33 @@
return false;
}
+ /**
+ * Is the first argument a indirection table entry and the other batch entry has
+ * a m:n reference to this indirection table?
+ */
+ private boolean isIndirectionTableOf(Batcher potentialIndirectionTable, Batcher potentialReference)
+ {
+ boolean result = false;
+ if(potentialIndirectionTable.isIndirectionTable() && potentialReference.getClassDescriptor() != null)
+ {
+ //System.out.println("# ind: " + potentialIndirectionTable);
+ //System.out.println("# ref: " + potentialReference);
+ List descriptors = potentialReference.getClassDescriptor().getCollectionDescriptors();
+ for(int i = 0; i < descriptors.size(); i++)
+ {
+ CollectionDescriptor colDes = (CollectionDescriptor) descriptors.get(i);
+ if(colDes.isMtoNRelation() && colDes.getIndirectionTableDescriptor().getTableName()
+ .equals(potentialIndirectionTable.getTableName()))
+ {
+ result = true;
+ break;
+ }
+ }
+ //System.out.println("result: " + result);
+ }
+ return result;
+ }
+
//-------------------- Inner classes -----------------------
/**
@@ -112,19 +135,12 @@
*/
public class InsertTranspositionBan implements TranspositionBan
{
- public boolean isBanned(BatchInfo infoNew,
- BatchInfo infoOld)
+ public boolean isBanned(Batcher infoNew, Batcher infoOld)
{
- return ((infoNew.getType() == BatchInfo.TYPE_OBJECT_INSERT)
-
- && ((infoOld.getType() == BatchInfo.TYPE_OBJECT_INSERT)
- || (infoOld.getType() == BatchInfo.TYPE_OBJECT_UPDATE))
-
- && (hasReferenceTo(infoOld, infoNew)
- || hasCollection1ToNOf(infoNew, infoOld))
-
- );
- // TODO M:N indirection table
+ return infoNew.isInsert() &&
+ (((infoOld.isInsert() || infoOld.isUpdate())
+ && (hasReferenceTo(infoOld, infoNew) || hasCollection1ToNOf(infoNew, infoOld))
+ ) || infoOld.isInsert() && isIndirectionTableOf(infoOld, infoNew));
}
}
@@ -136,19 +152,12 @@
*/
public class DeleteTranspositionBan implements TranspositionBan
{
- public boolean isBanned(BatchInfo infoNew,
- BatchInfo infoOld)
+ public boolean isBanned(Batcher infoNew, Batcher infoOld)
{
- return (((infoNew.getType() == BatchInfo.TYPE_OBJECT_DELETE)
- || (infoNew.getType() == BatchInfo.TYPE_OBJECT_UPDATE))
-
- && (infoOld.getType() == BatchInfo.TYPE_OBJECT_DELETE)
-
- && (hasReferenceTo(infoNew, infoOld)
- || hasCollection1ToNOf(infoOld, infoNew))
-
- );
- // TODO M:N indirection table
+ return (infoNew.isDelete() || infoNew.isUpdate()) &&
+ (((infoOld.isDelete()) &&
+ (hasReferenceTo(infoNew, infoOld) || hasCollection1ToNOf(infoOld, infoNew))
+ ) || infoOld.isDelete() && isIndirectionTableOf(infoNew, infoOld));
}
}
@@ -159,28 +168,14 @@
*/
public class TheSameTableTranspositionBan implements TranspositionBan
{
- public boolean isBanned(BatchInfo infoNew,
- BatchInfo infoOld)
+ public boolean isBanned(Batcher infoNew,
+ Batcher infoOld)
{
- // TODO M:N indirection table
- return (
- infoNew.getCld() != null
- && infoOld.getCld() != null
- && infoNew.getCld().getFullTableName().equals(infoOld.getCld().getFullTableName())
- &&
+ return infoNew.getTableName().equals(infoOld.getTableName()) &&
(
- ((infoNew.getType() == BatchInfo.TYPE_OBJECT_INSERT)
- && (infoOld.getType() == BatchInfo.TYPE_OBJECT_UPDATE))
-
- || ((infoNew.getType() == BatchInfo.TYPE_OBJECT_UPDATE)
- && (infoOld.getType() == BatchInfo.TYPE_OBJECT_DELETE))
-
- || ((infoNew.getType() == BatchInfo.TYPE_OBJECT_INSERT)
- && (infoOld.getType() == BatchInfo.TYPE_OBJECT_DELETE))
-
- || ((infoNew.getType() == BatchInfo.TYPE_OBJECT_DELETE)
- && (infoOld.getType() == BatchInfo.TYPE_OBJECT_INSERT))
- )
+ (infoNew.isInsert() && (infoOld.isUpdate() || infoOld.isDelete()))
+ || (infoNew.isUpdate() && infoOld.isDelete())
+ || (infoNew.isDelete() && infoOld.isInsert())
);
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidator.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidator.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidator.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidator.java Fri Jan 12 10:19:39 2007
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-import java.lang.Object;
import java.sql.SQLException;
import org.apache.ojb.broker.OptimisticLockException;
@@ -34,11 +33,13 @@
* results (number of affected rows) with the <em>real</em> returned result array.
*
* @param platform The used platform.
- * @param info The {@link BatchInfo} batch metadata.
- * @param expectedResults The expected return value array.
+ * @param batcher The {@link Batcher} instance.
* @param result The real return value array.
- * @throws java.sql.SQLException If the return values are illegal or signal batch entries execution failures.
+ * @throws java.sql.SQLException If the return values are illegal or signal
+ * batch entries execution failures.
* @throws org.apache.ojb.broker.OptimisticLockException If an optimistic lock issue occur.
*/
- void validateResult(Platform platform, BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException;
+ void validateResult(Platform platform, Batcher batcher, int[] result)
+ throws SQLException, OptimisticLockException;
+
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidatorImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidatorImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidatorImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/batch/ReturnValueValidatorImpl.java Fri Jan 12 10:19:39 2007
@@ -36,18 +36,7 @@
{
}
- /**
- * Validates the batch statement execution result value array by comparing the expected
- * results (number of affected rows) with the <em>real</em> returned result array.
- *
- * @param platform The used platform.
- * @param info The {@link org.apache.ojb.broker.accesslayer.batch.BatchInfo} batch metadata.
- * @param expectedResults The expected return value array.
- * @param result The real return value array.
- * @throws SQLException If the return values are illegal or signal batch entries execution failures.
- * @throws OptimisticLockException If an optimistic lock issue occur.
- */
- public void validateResult(Platform platform, BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ public void validateResult(Platform platform, Batcher batcher, int[] result) throws SQLException, OptimisticLockException
{
/*
a batch execution failed when
@@ -56,27 +45,28 @@
- it signal a failure while statement execution
- optimistic lock issue
*/
+ int[] expectedResults = batcher.getExpectedResults();
if(result != null && result.length == expectedResults.length)
{
- switch(info.getType())
+ switch(batcher.getType())
{
- case BatchInfo.TYPE_OBJECT_UPDATE:
- validateUpdate(info, expectedResults, result);
+ case Batcher.TYPE_UPDATE:
+ validateUpdate(batcher, expectedResults, result);
break;
- case BatchInfo.TYPE_OBJECT_INSERT:
- validateInsert(info, expectedResults, result);
+ case Batcher.TYPE_INSERT:
+ validateInsert(batcher, expectedResults, result);
break;
- case BatchInfo.TYPE_OBJECT_DELETE:
- validateDelete(info, expectedResults, result);
+ case Batcher.TYPE_DELETE:
+ validateDelete(batcher, expectedResults, result);
break;
- case BatchInfo.TYPE_INDIRECTION_TABLE_DELETE:
- validateIndirectionTableDelete(info, expectedResults, result);
+ case Batcher.TYPE_INDIRECTION_TABLE_DELETE:
+ validateIndirectionTableDelete(batcher, expectedResults, result);
break;
- case BatchInfo.TYPE_INDIRECTION_TABLE_INSERT:
- validateIndirectionTableInsert(info, expectedResults, result);
+ case Batcher.TYPE_INDIRECTION_TABLE_INSERT:
+ validateIndirectionTableInsert(batcher, expectedResults, result);
break;
default:
- validateUnkownType(info, expectedResults, result);
+ validateUnkownType(batcher, expectedResults, result);
}
}
else
@@ -91,13 +81,13 @@
/**
* FOR INTERNAL USE ONLY! Validates UPDATE operation batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateUpdate(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateUpdate(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
@@ -106,29 +96,29 @@
{
if(resultValue == PreparedStatement.EXECUTE_FAILED)
{
- throw throwExecuteFailed(info, expectedResults, result, i);
+ throw throwExecuteFailed(batcher, expectedResults, result, i);
}
- else if(info.useOptimisticLocking())
+ else if(batcher.useOptimisticLocking())
{
// on insert of objects with enabled opt. locking we allow unverified
// return values, otherwise we throw an exception
if(resultValue == Statement.SUCCESS_NO_INFO)
{
- if(info.getType() != BatchInfo.TYPE_OBJECT_INSERT)
+ if(batcher.getType() != Batcher.TYPE_INSERT)
{
- throw throwJdbcNotSupported(info, expectedResults, result, i);
+ throw throwJdbcNotSupported(batcher, expectedResults, result, i);
}
}
else
{
- throw throwOptimisticLock(info, expectedResults, result, i);
+ throw throwOptimisticLock(batcher, expectedResults, result, i);
}
}
else if(!(resultValue == PreparedStatement.SUCCESS_NO_INFO
|| resultValue == PreparedStatement.CLOSE_ALL_RESULTS
|| resultValue == 0))
{
- throw throwUnexpectedValue(info, expectedResults, result, i);
+ throw throwUnexpectedValue(batcher, expectedResults, result, i);
}
}
}
@@ -137,13 +127,13 @@
/**
* FOR INTERNAL USE ONLY! Validates INSERT operation batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateInsert(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateInsert(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
@@ -152,11 +142,11 @@
{
if(resultValue == PreparedStatement.EXECUTE_FAILED)
{
- throw throwExecuteFailed(info, expectedResults, result, i);
+ throw throwExecuteFailed(batcher, expectedResults, result, i);
}
else if(resultValue != PreparedStatement.SUCCESS_NO_INFO)
{
- throw throwUnexpectedValue(info, expectedResults, result, i);
+ throw throwUnexpectedValue(batcher, expectedResults, result, i);
}
}
}
@@ -165,13 +155,13 @@
/**
* FOR INTERNAL USE ONLY! Validates DELETE operation batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateDelete(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateDelete(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
@@ -180,28 +170,28 @@
{
if(resultValue == PreparedStatement.EXECUTE_FAILED)
{
- throw throwExecuteFailed(info, expectedResults, result, i);
+ throw throwExecuteFailed(batcher, expectedResults, result, i);
}
- else if(info.useOptimisticLocking())
+ else if(batcher.useOptimisticLocking())
{
// on insert of objects with enabled opt. locking we allow unverified
// return values, otherwise we throw an exception
if(resultValue == Statement.SUCCESS_NO_INFO)
{
- if(info.getType() != BatchInfo.TYPE_OBJECT_INSERT)
+ if(batcher.getType() != Batcher.TYPE_INSERT)
{
- throw throwJdbcNotSupported(info, expectedResults, result, i);
+ throw throwJdbcNotSupported(batcher, expectedResults, result, i);
}
}
else
{
- throw throwOptimisticLock(info, expectedResults, result, i);
+ throw throwOptimisticLock(batcher, expectedResults, result, i);
}
}
else if(!(resultValue == PreparedStatement.SUCCESS_NO_INFO
|| resultValue == 0))
{
- throw throwUnexpectedValue(info, expectedResults, result, i);
+ throw throwUnexpectedValue(batcher, expectedResults, result, i);
}
}
}
@@ -210,13 +200,13 @@
/**
* FOR INTERNAL USE ONLY! Validates m:n-INDIRECTIONTABLE-INSERT operation batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateIndirectionTableInsert(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateIndirectionTableInsert(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
@@ -227,11 +217,11 @@
{
if(resultValue == PreparedStatement.EXECUTE_FAILED)
{
- throw throwExecuteFailed(info, expectedResults, result, i);
+ throw throwExecuteFailed(batcher, expectedResults, result, i);
}
else if(resultValue != PreparedStatement.SUCCESS_NO_INFO)
{
- throw throwUnexpectedValue(info, expectedResults, result, i);
+ throw throwUnexpectedValue(batcher, expectedResults, result, i);
}
}
}
@@ -240,13 +230,13 @@
/**
* FOR INTERNAL USE ONLY! Validates m:n-INDIRECTIONTABLE-DELETE operation batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateIndirectionTableDelete(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateIndirectionTableDelete(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
@@ -256,13 +246,13 @@
{
if(resultValue == PreparedStatement.EXECUTE_FAILED)
{
- throw throwExecuteFailed(info, expectedResults, result, i);
+ throw throwExecuteFailed(batcher, expectedResults, result, i);
}
else if(!(resultValue == PreparedStatement.SUCCESS_NO_INFO
|| resultValue == PreparedStatement.CLOSE_ALL_RESULTS
|| resultValue == 0))
{
- throw throwUnexpectedValue(info, expectedResults, result, i);
+ throw throwUnexpectedValue(batcher, expectedResults, result, i);
}
}
}
@@ -271,30 +261,30 @@
/**
* FOR INTERNAL USE ONLY! Validates UNKOWN TYPES of batch statement execution results.
*
- * @param info The {@link BatchInfo} batch metadata.
+ * @param batcher The {@link Batcher} batch metadata.
* @param expectedResults The expected return value array.
* @param result The real return value array.
* @throws SQLException If the return values are illegal or signal batch entries execution failures.
* @throws OptimisticLockException If an optimistic lock issue occur.
*/
- protected void validateUnkownType(BatchInfo info, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
+ protected void validateUnkownType(Batcher batcher, int[] expectedResults, int[] result) throws SQLException, OptimisticLockException
{
for(int i = 0; i < result.length; i++)
{
int resultValue = result[i];
if(resultValue == Statement.EXECUTE_FAILED)
{
- throwExecuteFailed(info, expectedResults, result, i);
+ throwExecuteFailed(batcher, expectedResults, result, i);
}
// arminw: when OJB perform an unkown batch sql-query we don't know the return value 0,1,2....
// if(expectedResults[i] > resultValue)
// {
-// throw throwUnexpectedValue(info, expectedResults, result, i);
+// throw throwUnexpectedValue(batcher, expectedResults, result, i);
// }
}
}
- protected SQLException throwExecuteFailed(BatchInfo info, int[] expectedResults, int[] result, int index)
+ protected SQLException throwExecuteFailed(Batcher batcher, int[] expectedResults, int[] result, int index)
{
String eol = SystemUtils.LINE_SEPARATOR;
return new SQLException(
@@ -304,7 +294,7 @@
"', but found " + ReflectionHelper.reflectNameFor(Statement.class, result[index]));
}
- protected SQLException throwJdbcNotSupported(BatchInfo info, int[] expectedResults, int[] result, int index)
+ protected SQLException throwJdbcNotSupported(Batcher batcher, int[] expectedResults, int[] result, int index)
{
String eol = SystemUtils.LINE_SEPARATOR;
return new SQLException("JDBC driver does support batch statements but does not"
@@ -316,10 +306,10 @@
+ eol + " Please use a more sophisticated JDBC driver or a BatchManager implementation"
+ eol + " which provide a specific property to exclude objects using optimistic locking"
+ eol + " from being put to batch (OJB's default impl. class supports such a property)."
- + eol + " Used BatchInfo instance: " + eol + info);
+ + eol + " Used Batcher instance: " + eol + batcher);
}
- protected SQLException throwUnexpectedValue(BatchInfo info, int[] expectedResults, int[] result, int index)
+ protected SQLException throwUnexpectedValue(Batcher batcher, int[] expectedResults, int[] result, int index)
{
return new SQLException("Execute batch returned an unexpected statement return" +
" value (row count result)." +
@@ -328,12 +318,12 @@
ReflectionHelper.reflectNameFor(Statement.class, result[index]));
}
- protected OptimisticLockException throwOptimisticLock(BatchInfo info, int[] expectedResults, int[] result, int index)
+ protected OptimisticLockException throwOptimisticLock(Batcher batcher, int[] expectedResults, int[] result, int index)
{
String eol = SystemUtils.LINE_SEPARATOR;
return new OptimisticLockException("Detect optimistic locking conflict while statement" +
" execution for batch command number '" + (index + 1) + "' of '" + result.length + "' commands" +
". Expected statement return value (row count) was '" + expectedResults[index] +
- "', but found '" + result[index] + "'." + eol + " Used BatchInfo instance: " + eol + info);
+ "', but found '" + result[index] + "'." + eol + " Used Batcher instance: " + eol + batcher);
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java Fri Jan 12 10:19:39 2007
@@ -19,9 +19,8 @@
import org.apache.ojb.broker.query.Query;
/**
- * This class
+ * Encapsulates methodes of select statements.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public interface SelectStatement extends SqlStatement
@@ -51,4 +50,9 @@
* case this method returns <em>true</em>.
*/
public boolean isUseOjbClassColumn();
+
+ /**
+ * Returns <em>true</em> if the statement is a stored procedure.
+ */
+ public boolean isStoredProcedure();
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureFKStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureFKStatement.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureFKStatement.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureFKStatement.java Fri Jan 12 10:19:39 2007
@@ -33,9 +33,6 @@
* Model a call to a stored procedure based on ProcedureDescriptors
*
* @see org.apache.ojb.broker.metadata.ProcedureDescriptor
- * @author <a href="mailto:[email protected]">Randall Burt</a>
- * @author <a href="mailto:[email protected]">Ron Gallagher</a>
- * @author <a href="mailto:[email protected]">Vadim Gritsenko</a>
* @version $Id$
*/
public class SqlProcedureFKStatement implements SelectStatement
@@ -140,5 +137,10 @@
public boolean isUseOjbClassColumn()
{
return false;
+ }
+
+ public boolean isStoredProcedure()
+ {
+ return true;
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureStatement.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureStatement.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlProcedureStatement.java Fri Jan 12 10:19:39 2007
@@ -25,8 +25,6 @@
* Model a call to a stored procedure based on ProcedureDescriptors
*
* @see org.apache.ojb.broker.metadata.ProcedureDescriptor
- * @author <a href="mailto:[email protected]">Randall Burt</a>
- * @author <a href="mailto:[email protected]">Ron Gallagher</a>
* @version $Id$
*/
@@ -107,5 +105,10 @@
public boolean isUseOjbClassColumn()
{
return false;
+ }
+
+ public boolean isStoredProcedure()
+ {
+ return true;
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java Fri Jan 12 10:19:39 2007
@@ -340,30 +340,9 @@
orderByFields = query.getOrderBy();
columnList = ensureColumns(orderByFields, columnList, stmt);
-/*
-arminw:
-TODO: this feature doesn't work, so remove this in future
-*/
- /**
- * treeder: going to map superclass tables here,
- * not sure about the columns, just using all columns for now
- */
- ClassDescriptor cld = getBaseClassDescriptor();
- ClassDescriptor cldSuper = null;
- if (cld.getSuperClass() != null)
- {
- // then we have a super class so join tables
- cldSuper = cld.getRepository().getDescriptorFor(cld.getSuperClass());
- appendSuperClassColumns(cldSuper, stmt);
- }
stmt.append(" FROM ");
appendTableWithJoins(getRootAlias(), where, stmt);
-
- if (cld.getSuperClass() != null)
- {
- appendSuperClassJoin(cld, cldSuper, stmt, where);
- }
appendWhereClause(where, whereCrit, stmt);
appendGroupByClause(groupByFields, stmt);
@@ -377,52 +356,16 @@
((ReportQueryByCriteria) query).setAttributeFieldDescriptors(getAttributesToFieldDescriptors());
}
- return stmt.toString();
- }
-
-/*
-arminw:
-TODO: this feature doesn't work, so remove this in future
-*/
- private void appendSuperClassJoin(ClassDescriptor cld, ClassDescriptor cldSuper, StringBuffer stmt, StringBuffer where)
- {
- stmt.append(",");
- appendTable(cldSuper, stmt);
-
- if (where != null)
+ if(query.isSelectForUpdate())
{
- if (where.length() > 0)
- {
- where.append(" AND ");
- }
-
- // get reference field in super class
- // TODO: do not use the superclassfield anymore, just assume that the id is the same in both tables - @see PBroker.storeToDb
- int superFieldRef = cld.getSuperClassFieldRef();
- FieldDescriptor refField = cld.getFieldDescriptorByIndex(superFieldRef);
-
- appendTable(cldSuper, where);
- where.append(".");
- appendField(cldSuper.getAutoIncrementFields()[0], where);
- where.append(" = ");
- appendTable(cld, where);
- where.append(".");
- appendField(refField, where);
+ stmt.append(getPlatform().getSelectForUpdateClause());
}
- }
-
- private void appendSuperClassColumns(ClassDescriptor cldSuper, StringBuffer buf)
- {
- FieldDescriptor[] fields = cldSuper.getFieldDescriptions();
- for (int i = 0; i < fields.length; i++)
+ if(query.getQueryAffix() != null)
{
- FieldDescriptor field = fields[i];
- if (i > 0)
- {
- buf.append(",");
- }
- appendColumn(cldSuper.getFullTableName(), field.getColumnName(), buf);
+ stmt.append(" ").append(query.getQueryAffix());
}
+
+ return stmt.toString();
}
/**
@@ -475,5 +418,10 @@
protected void setUseOjbClassColumn(boolean useOjbClassColumn)
{
this.useOjbClassColumn = useOjbClassColumn;
+ }
+
+ public boolean isStoredProcedure()
+ {
+ return false;
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/cache/AbstractObjectCache.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/cache/AbstractObjectCache.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/cache/AbstractObjectCache.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/cache/AbstractObjectCache.java Fri Jan 12 10:19:39 2007
@@ -1,11 +1,11 @@
package org.apache.ojb.broker.cache;
import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
-import org.apache.commons.collections.map.ReferenceIdentityMap;
-import org.apache.commons.collections.map.ReferenceMap;
import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.util.WeakIdentityList;
/* Copyright 2002-2004 The Apache Software Foundation
*
@@ -23,33 +23,41 @@
*/
/**
- * Base class to provide the extended functionality of {@link ObjectCacheExt}
- * to all {@link ObjectCache} implementations extending this class.
+ * Base class to provide the common functionality of {@link ObjectCache}.
*
* @version $Id$
*/
-abstract public class AbstractObjectCache implements ObjectCacheExt
+abstract public class AbstractObjectCache implements ObjectCache
{
- private final Object dummy = new Object();
- private Map listeners;
+ private final Object sync = new Object();
+ private List listeners;
- private Map createListenerMap()
+ /**
+ * Implement this method to cache objects.
+ *
+ * @param oid The {@link org.apache.ojb.broker.Identity} of the object.
+ * @param obj The object to cache.
+ */
+ abstract public void doCache(Identity oid, Object obj);
+
+ /**
+ * Internally called for each object cached by this cache implementation.
+ *
+ * @param oid The {@link org.apache.ojb.broker.Identity} of the cached object.
+ */
+ void performInvalidationAction(Identity oid)
{
- return new ReferenceIdentityMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
- }
-
- protected void performInvalidationAction(Identity oid)
- {
- if(listeners == null) return;
-
- synchronized(dummy)
+ if(listeners != null)
{
- Iterator it = listeners.keySet().iterator();
- InvalidationListener target;
- while(it.hasNext())
+ synchronized(sync)
{
- target = (InvalidationListener) it.next();
- if(target != null) target.invalidateObject(oid);
+ Iterator it = listeners.iterator();
+ InvalidationListener target;
+ while(it.hasNext())
+ {
+ target = (InvalidationListener) it.next();
+ if(target != null) target.invalidateObject(oid);
+ }
}
}
}
@@ -60,15 +68,13 @@
{
throw new NullPointerException("Added InvalidationListener can't be 'null'");
}
- if(listeners == null)
+ synchronized(sync)
{
- listeners = createListenerMap();
- }
- // dummy value
- Integer id = new Integer(System.identityHashCode(listener));
- synchronized(dummy)
- {
- if(!listeners.containsKey(listener)) listeners.put(listener, id);
+ if(listeners == null)
+ {
+ listeners = new WeakIdentityList();
+ }
+ if(!listeners.contains(listener)) listeners.add(listener);
}
}
@@ -79,7 +85,7 @@
{
throw new NullPointerException("InvalidationListener can't be 'null'");
}
- synchronized(dummy)
+ synchronized(sync)
{
listeners.remove(listener);
if(listeners.size() == 0)
@@ -89,25 +95,50 @@
}
}
+ public List getAllInvalidationListener()
+ {
+ List result = new ArrayList();
+ synchronized(sync)
+ {
+ Iterator it = listeners.iterator();
+ while(it.hasNext())
+ {
+ result.add(it.next());
+ }
+ }
+ return result;
+ }
+
public void invalidateObject(Identity oid)
{
/*
- invalidate object by direct call to the underlying ObjectCacheExt
+ invalidate object by direct call to the underlying cache
instance, never use the #remove(oid) method to invalidate to avoid problems
with caches which add each other as listener.
*/
remove(oid);
}
+ /**
+ * Not allowed to override this method to guaratee call of
+ * invalidation action. Use methode {@link #doCache(org.apache.ojb.broker.Identity, Object)}
+ * to implement cache method.
+ */
+ final public void cache(final Identity oid, final Object obj)
+ {
+ doCache(oid, obj);
+ performInvalidationAction(oid);
+ }
+
public String toString()
{
StringBuffer msg = new StringBuffer();
- synchronized(dummy)
+ synchronized(sync)
{
if(listeners != null && listeners.size() > 0)
{
msg.append("Registered listener: ");
- Iterator it = listeners.keySet().iterator();
+ Iterator it = listeners.iterator();
boolean first = true;
while(it.hasNext())
{
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.