User: dsundstrom
Date: 02/01/15 14:33:08
Modified: src/main/org/jboss/ejb/plugins/cmp/jdbc
JDBCLoadEntityCommand.java
Log:
Added support for merged CMR field and CMP field interface.
Added support for new ReadAheadCache.
Merged functions from JDBCLoadFieldCommand and JDBCReadAheadCommand.
Revision Changes Path
1.14 +164 -54
jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/JDBCLoadEntityCommand.java
Index: JDBCLoadEntityCommand.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/JDBCLoadEntityCommand.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- JDBCLoadEntityCommand.java 2002/01/05 12:08:51 1.13
+++ JDBCLoadEntityCommand.java 2002/01/15 22:33:08 1.14
@@ -11,15 +11,20 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
import javax.ejb.EJBException;
import javax.ejb.NoSuchEntityException;
import org.jboss.ejb.EntityEnterpriseContext;
+import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData;
import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCTypeMappingMetaData;
import org.jboss.logging.Logger;
+import org.jboss.util.FinderResults;
/**
* JDBCLoadEntityCommand loads the data for an instance from the table.
@@ -28,18 +33,19 @@
* helpful for entitys with lots of data.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Dain Sundstrom</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Nitz</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Dirk Zimmermann</a>
* @author <a href="mailto:[EMAIL PROTECTED]">danch (Dan Christopherson)</a>
- * @version $Revision: 1.13 $
+ * @version $Revision: 1.14 $
*/
public class JDBCLoadEntityCommand {
- private JDBCStoreManager manager;
- private JDBCEntityBridge entity;
- private Logger log;
+ private final JDBCStoreManager manager;
+ private final JDBCEntityBridge entity;
+ private final Logger log;
public JDBCLoadEntityCommand(JDBCStoreManager manager) {
this.manager = manager;
@@ -53,42 +59,37 @@
}
public void execute(EntityEnterpriseContext ctx) {
- // load the instance primary key fields
+ execute(null, ctx);
+ }
+
+ public void execute(
+ JDBCCMPFieldBridge requiredField,
+ EntityEnterpriseContext ctx) {
+
+ // load the instance primary key fields into the context
entity.injectPrimaryKeyIntoInstance(ctx, ctx.getId());
+
+ // get the read ahead cache
+ ReadAheadCache readAheadCache = manager.getReadAheadCache();
+
+ // load any preloaded fields into the context
+ readAheadCache.load(ctx);
// determine the fields to load
- JDBCCMPFieldBridge[] loadFields = getLoadFields(ctx);
+ List loadFields = getLoadFields(requiredField, ctx);
// if no there are not load fields return
- if(loadFields.length == 0) {
+ if(loadFields.size() == 0) {
return;
}
- // generate the sql
- StringBuffer sql = new StringBuffer();
- String columnNamesClause = SQLUtil.getColumnNamesClause(loadFields);
- String tableName = entity.getTableName();
- String whereClause = SQLUtil.getWhereClause(entity.getJDBCPrimaryKeyFields());
+ // get the finder results associated with this context, if it exists
+ ReadAheadCache.EntityReadAheadInfo info =
+ readAheadCache.getEntityReadAheadInfo(ctx.getId());
+ List loadKeys = info.getLoadKeys();
- if (entity.getMetaData().hasRowLocking())
- {
- JDBCFunctionMappingMetaData rowLocking =
manager.getMetaData().getTypeMapping().getRowLockingTemplate();
- if (rowLocking == null)
- {
- throw new IllegalStateException("row-locking is not allowed for this
type of datastore");
- }
- else
- {
- String[] args = new String[] {columnNamesClause, tableName,
whereClause};
- sql.append(rowLocking.getFunctionSql(args));
- }
- }
- else
- {
- sql.append("SELECT ").append(columnNamesClause);
- sql.append(" FROM ").append(tableName);
- sql.append(" WHERE ").append(whereClause);
- }
+ // generate the sql
+ String sql = getSQL(loadFields, loadKeys.size());
Connection con = null;
PreparedStatement ps = null;
@@ -97,29 +98,70 @@
con = entity.getDataSource().getConnection();
// create the statement
- if (log.isDebugEnabled())
- log.debug("Executing SQL: " + sql);
- ps = con.prepareStatement(sql.toString());
+ log.debug("Executing SQL: " + sql);
+ ps = con.prepareStatement(sql);
// set the parameters
- entity.setPrimaryKeyParameters(ps, 1, ctx.getId());
+
+ int paramIndex = 1;
+ for(Iterator iter = loadKeys.iterator(); iter.hasNext();) {
+ paramIndex = entity.setPrimaryKeyParameters(
+ ps, paramIndex, iter.next());
+ }
// execute statement
ResultSet rs = ps.executeQuery();
- // did we get results
- if(!rs.next()) {
- throw new NoSuchEntityException("Entity " + ctx.getId() +
- " not found");
+ // load results
+ boolean mainEntityLoaded = false;
+ Object[] ref = new Object[1];
+ while(rs.next()) {
+ // reset the column index for this row
+ int index = 1;
+
+ // ref must be reset to null before load
+ ref[0] = null;
+
+ // if we are loading more then one entity, load the pk from the row
+ Object pk = null;
+ if(loadKeys.size() > 1) {
+ // load the pk
+ index = entity.loadPrimaryKeyResults(rs, index, ref);
+ pk = ref[0];
+ }
+
+ // is this the main entity or a preload entity
+ if(loadKeys.size()==1 || pk.equals(ctx.getId())) {
+ // main entity; load the values into the context
+ for(Iterator iter = loadFields.iterator(); iter.hasNext();) {
+ JDBCFieldBridge field = (JDBCFieldBridge)iter.next();
+ index = field.loadInstanceResults(rs, index, ctx);
+ field.setClean(ctx);
+ }
+ mainEntityLoaded = true;
+ } else {
+ // preload entity; load the values into the read ahead cahce
+ for(Iterator iter = loadFields.iterator(); iter.hasNext();) {
+ JDBCFieldBridge field = (JDBCFieldBridge)iter.next();
+
+ // ref must be reset to null before load
+ ref[0] = null;
+
+ // load the result of the field
+ index = field.loadArgumentResults(rs, index, ref);
+
+ // cache the field value
+ readAheadCache.addPreloadData(pk, field, ref[0]);
+ }
+ }
}
- // load each field and mark it clean
- int index = 1;
- for(int i=0; i<loadFields.length; i++) {
- index = loadFields[i].loadInstanceResults(rs, index, ctx);
- loadFields[i].setClean(ctx);
+ // did we load the main results
+ if(!mainEntityLoaded) {
+ throw new NoSuchEntityException("Entity not found: primaryKey=" +
+ ctx.getId());
}
-
+
// mark the entity as created; if it was loaded it was created
entity.setCreated(ctx);
} catch(EJBException e) {
@@ -132,17 +174,85 @@
}
}
- private JDBCCMPFieldBridge[] getLoadFields(EntityEnterpriseContext ctx) {
- JDBCCMPFieldBridge[] eagerFields = entity.getEagerLoadFields();
- ArrayList fields = new ArrayList(eagerFields.length);
-
- for(int i=0; i<eagerFields.length; i++) {
- if(!eagerFields[i].isPrimaryKeyMember() &&
- eagerFields[i].isReadTimedOut(ctx)) {
- fields.add(eagerFields[i]);
+ private String getSQL(List loadFields, int keyCount) {
+ //
+ // column names clause
+ StringBuffer columnNamesClause = new StringBuffer();
+ // if we are loading more then one entity we need to add the primry
+ // key to the load fields to match up the results with the correct
+ // entity.
+ if(keyCount > 1) {
+ columnNamesClause.append(SQLUtil.getColumnNamesClause(
+ entity.getPrimaryKeyFields()));
+ columnNamesClause.append(",");
+ }
+ columnNamesClause.append(SQLUtil.getColumnNamesClause(loadFields));
+
+ //
+ // table name clause
+ String tableName = entity.getTableName();
+
+ //
+ // where clause
+ String pkWhere = SQLUtil.getWhereClause(entity.getPrimaryKeyFields());
+ StringBuffer whereClause = new StringBuffer(
+ (pkWhere.length() + 6) * keyCount + 4);
+ for(int i=0; i<keyCount; i++) {
+ if(i > 0) {
+ whereClause.append(" OR ");
+ }
+ whereClause.append("(").append(pkWhere).append(")");
+ }
+
+ //
+ // assemble pieces into final statement
+ if(entity.getMetaData().hasRowLocking()) {
+ JDBCFunctionMappingMetaData rowLocking =
+ manager.getMetaData().getTypeMapping().getRowLockingTemplate();
+ if(rowLocking == null) {
+ throw new IllegalStateException("row-locking is not allowed for " +
+ "this type of datastore");
+ } else {
+ String[] args = new String[] {
+ columnNamesClause.toString(),
+ tableName,
+ whereClause.toString()};
+ return rowLocking.getFunctionSql(args);
+ }
+ } else {
+ StringBuffer sql = new StringBuffer(
+ 7 + columnNamesClause.length() +
+ 6 + tableName.length() +
+ 7 + whereClause.length());
+
+ sql.append("SELECT ").append(columnNamesClause);
+ sql.append(" FROM ").append(tableName);
+ sql.append(" WHERE ").append(whereClause);
+ return sql.toString();
+ }
+
+ }
+
+ private List getLoadFields(
+ JDBCCMPFieldBridge requiredField,
+ EntityEnterpriseContext ctx) {
+
+ ArrayList fields = new ArrayList(entity.getEagerLoadFields());
+ if(requiredField != null && !fields.contains(requiredField)) {
+ fields.add(requiredField);
+ }
+
+ // remove any field that is a member of the primary key
+ // or has not timed out or is already loaded
+ for(Iterator iter=fields.iterator(); iter.hasNext();) {
+ JDBCFieldBridge field = (JDBCFieldBridge)iter.next();
+ if(field.isPrimaryKeyMember() ||
+ !field.isReadTimedOut(ctx) ||
+ field.isLoaded(ctx)) {
+ iter.remove();
}
}
- return (JDBCCMPFieldBridge[])fields.toArray(
- new JDBCCMPFieldBridge[fields.size()]);
+
+ return fields;
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development