User: danch Date: 01/06/12 23:52:17 Modified: src/main/org/jboss/ejb/plugins/jaws/jdbc JDBCCommandFactory.java JDBCDefinedFinderCommand.java JDBCFindAllCommand.java JDBCFindByCommand.java JDBCFinderCommand.java JDBCLoadEntitiesCommand.java JDBCLoadEntityCommand.java Log: second pass at collection finder optimization - this fixes problem with defined finders doing joins Revision Changes Path 1.9 +149 -1 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommandFactory.java Index: JDBCCommandFactory.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommandFactory.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- JDBCCommandFactory.java 2001/05/27 17:59:00 1.8 +++ JDBCCommandFactory.java 2001/06/13 06:52:17 1.9 @@ -8,9 +8,16 @@ package org.jboss.ejb.plugins.jaws.jdbc; import java.lang.reflect.Method; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; import javax.naming.Context; import javax.naming.InitialContext; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; import org.jboss.ejb.EntityContainer; import org.jboss.ejb.DeploymentException; @@ -38,13 +45,14 @@ import org.jboss.ejb.plugins.jaws.metadata.FinderMetaData; import org.jboss.logging.Log; +import org.jboss.util.FinderResults; /** * JAWSPersistenceManager JDBCCommandFactory * * @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a> * @author <a href="[EMAIL PROTECTED]">danch (Dan Christopherson</a> - * @version $Revision: 1.8 $ + * @version $Revision: 1.9 $ */ public class JDBCCommandFactory implements JPMCommandFactory { @@ -56,6 +64,20 @@ private Log log; private boolean debug = false; + /** a map of data preloaded within some transaction for some entity. This map + * is keyed by Transaction and the data are hashmaps with key = entityKey and + * data = Object[] containing the entity data. + * @todo use weak references to ease memory. */ + private Map preloadedData = new HashMap(); + /** A map of data preloaded without a transaction context. key=entityKey, + * data = Object[] containing entity data + * @todo use weak references to ease memory. + */ + private Map nonTransactionalPreloadData = new HashMap(); + + /** a Transaction manager so that we can link preloaded data to a transaction */ + private TransactionManager tm; + // These support singletons (within the scope of this factory) private JDBCBeanExistsCommand beanExistsCommand; private JPMFindEntitiesCommand findEntitiesCommand; @@ -87,6 +109,8 @@ if (metadata == null) { throw new DeploymentException("No metadata found for bean " + ejbName); } + + tm = (TransactionManager) container.getTransactionManager(); } // Public -------------------------------------------------------- @@ -231,5 +255,129 @@ } + /** Add preloaded data for an entity within the scope of a transaction */ + /*package*/ void addPreloadData(Object entityKey, Object[] entityData) + { + Transaction trans = null; + try { + trans = tm.getTransaction(); + } catch (javax.transaction.SystemException sysE) { + log.warning("System exception getting transaction for preload - can't get preloaded data for "+entityKey); + return; + } +//log.debug("PRELOAD: adding preload for "+entityKey+" in transaction "+(trans != null ? trans.toString() : "NONE")); + + if (trans != null) { + synchronized (preloadedData) { + Map entitiesInTransaction = (Map)preloadedData.get(trans); + if (entitiesInTransaction == null) { + try { + trans.registerSynchronization(new PreloadClearSynch(trans)); + } catch (javax.transaction.SystemException se) { + log.warning("System exception getting transaction for preload - can't get preloaded data for "+entityKey); + return; + } catch (javax.transaction.RollbackException re) { + log.warning("Rollback exception getting transaction for preload - can't get preloaded data for "+entityKey); + return; + } + entitiesInTransaction = new HashMap(); + preloadedData.put(trans, entitiesInTransaction); + } + entitiesInTransaction.put(entityKey, entityData); + } + } else { + synchronized (nonTransactionalPreloadData) { + nonTransactionalPreloadData.put(entityKey, entityData); + } + } + } + + /** get data that we might have preloaded for an entity in a transaction - + * may return null! + */ + /*package*/ Object[] getPreloadData(Object entityKey) + { + Transaction trans = null; + try { + trans = tm.getTransaction(); + } catch (javax.transaction.SystemException sysE) { + log.warning("System exception getting transaction for preload - not preloading "+entityKey); + return null; + } + + Object[] result = null; + if (trans != null) { + synchronized (preloadedData) { + Map entitiesInTransaction = (Map)preloadedData.get(trans); + if (entitiesInTransaction != null) + result = (Object[])entitiesInTransaction.get(entityKey); + //remove it now? + } + } else { + synchronized (nonTransactionalPreloadData) { + result = (Object[])nonTransactionalPreloadData.get(entityKey); + } + } +//log.debug("PRELOAD: returning "+result+" as preload for "+entityKey); + return result; + } + + /** clear out any data we have preloaded for any entity in this transaction */ + /*package*/ void clearPreloadForTrans(Transaction trans) + { +//log.debug("PRELOAD: clearing preload for transaction "+trans.toString()); + synchronized (preloadedData) { + preloadedData.remove(trans); + } + } + + // Private ------------------------------------------------------- + /** an inner class used to key the FinderResults by their finder method and + * the transaction they're invoked within + */ + private static class PreloadDataKey { + private Object entityKey; + private Transaction transaction; + + private int hashCode; + + public PreloadDataKey(Object entityKey, Transaction transaction) { + this.entityKey = entityKey; + this.transaction = transaction; + + //accumulate the hashcode. + /** @todo investigate ways of combining these that will give the least collisions */ + this.hashCode = entityKey.hashCode(); + if (transaction != null) + this.hashCode += transaction.hashCode(); + } + + public int hashCode() { + return hashCode; + } + public boolean equals(Object o) { + if (o instanceof PreloadDataKey) { + PreloadDataKey other = (PreloadDataKey)o; + return (other.entityKey.equals(this.entityKey)) && + ( (other.transaction == null && this.transaction == null) || + ( (other.transaction != null && this.transaction != null) && + (other.transaction.equals(this.transaction)) ) ); + } + return false; + } + } + + private class PreloadClearSynch implements javax.transaction.Synchronization{ + private Transaction forTrans; + public PreloadClearSynch(Transaction forTrans) { + this.forTrans = forTrans; + } + public void afterCompletion(int p0) { + clearPreloadForTrans(forTrans); + } + public void beforeCompletion() { + //no-op + } + } } 1.14 +130 -107 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCDefinedFinderCommand.java Index: JDBCDefinedFinderCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCDefinedFinderCommand.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- JDBCDefinedFinderCommand.java 2001/05/27 17:59:00 1.13 +++ JDBCDefinedFinderCommand.java 2001/06/13 06:52:17 1.14 @@ -26,8 +26,9 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a> * @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a> * @author <a href="mailto:[EMAIL PROTECTED]">Michel de Groot</a> - * @author <a href="[EMAIL PROTECTED]">danch (Dan Christopherson</a> - * @version $Revision: 1.13 $ + * @author Vinay Menon + * @author <a href="mailto:[EMAIL PROTECTED]">danch (Dan Christopherson</a> + * @version $Revision: 1.14 $ */ public class JDBCDefinedFinderCommand extends JDBCFinderCommand { @@ -35,6 +36,10 @@ private int[] parameterArray; private TypeMappingMetaData typeMapping; + + private String fromClause = ""; + private String whereClause = ""; + private String orderClause = ""; // Constructors -------------------------------------------------- @@ -72,36 +77,128 @@ // Since the fields in order clause also will form the select clause together with // the pk field list, we have to clean the order clause from ASC/DESC's and fields // that already are within the pk list + // Note that extraOrderColumns will start with a ',' + String extraOrderColumns = getExtraOrderColumns(f); + + String lcQuery = query.toLowerCase(); + // build from clause, including any joins specified by the deployer/assembler + // In case of join query: + // order must explicitly identify tablename.field to order on + // query must start with "INNER JOIN <table to join with> WHERE + // <regular query with fully identified fields>" + if (lcQuery.startsWith(",") || lcQuery.startsWith("inner join")) { + //this is the case of a 'where' that is build to actually join tables: + // ,table2 as foo where foo.col1 = entitytable.col2 AND entitytable.filter = {1} + // or + // inner join table2 on table2.col1 = entitytable.col2 AND entitytable.filter = {1} + String tableList = null; + int whereStart = lcQuery.indexOf("where"); + if (whereStart == -1) { + //log this at debug in case someone has made a mistake, but assume that + // they mean a findAll. + log.debug("Strange query for finder "+f.getName()+ + ". Includes join, but no 'where' clause. Is this a findAll?"); + tableList = lcQuery; + whereClause = ""; + } else { + tableList = lcQuery.substring(0, whereStart); + whereClause = lcQuery.substring(whereStart); + } + fromClause = "FROM "+jawsEntity.getTableName()+tableList; + } else { + fromClause = "FROM "+jawsEntity.getTableName(); + if (lcQuery.startsWith("where")) + whereClause = lcQuery; + else + whereClause = "where "+lcQuery; + } + + + StringBuffer sqlBuffer = new StringBuffer(); + sqlBuffer.append("SELECT "); + //where clauseString primaryKeyList = getPkColumnList(); + String tableName = jawsEntity.getTableName(); + StringTokenizer stok = new StringTokenizer(getPkColumnList(),","); + + while(stok.hasMoreTokens()){ + sqlBuffer.append(tableName); + sqlBuffer.append("."); + sqlBuffer.append(stok.nextElement().toString()); + sqlBuffer.append(","); + } + // ditch the last ',' at the end... + sqlBuffer.setLength(sqlBuffer.length()-1); + // because it's already on the front of extraOrderColumns + sqlBuffer.append(extraOrderColumns); + sqlBuffer.append(' '); + sqlBuffer.append(fromClause); + sqlBuffer.append(' '); + sqlBuffer.append(whereClause); + + if (f.getOrder() != null && !f.getOrder().equals("")) + { + orderClause = " ORDER BY "+f.getOrder(); + sqlBuffer.append(orderClause); + } + setSQL(sqlBuffer.toString()); + } + + public String getWhereClause() { + return whereClause; + } + + public String getFromClause() { + return fromClause; + } + public String getOrderByClause() { + return orderClause; + } + + /** helper method to clean the order clause into a list of table.field + * entries. This is used only to clean up the algorythm in the ctor. + * @return String array containing order fields stripped of 'ASC' or 'DESC' + * modifiers. + */ + protected String[] cleanOrderClause(String rawOrder) { + //Split it into tokens. These tokens might contain ASC/DESC that we have to get rid of + StringTokenizer orderTokens = new StringTokenizer(rawOrder, ","); + String orderToken; + String[] checkedOrderTokens = new String[orderTokens.countTokens()]; + int ix = 0; + while(orderTokens.hasMoreTokens()) + { + orderToken = orderTokens.nextToken().trim(); + //Get rid of ASC's + int i = orderToken.toUpperCase().indexOf(" ASC"); + if(i!=-1) + checkedOrderTokens[ix] = orderToken.substring(0, i).trim(); + else + { + //Get rid of DESC's + i = orderToken.toUpperCase().indexOf(" DESC"); + if(i!=-1) + checkedOrderTokens[ix] = orderToken.substring(0, i).trim(); + else + { + //No ASC/DESC - just use it as it is + checkedOrderTokens[ix] = new String(orderToken).trim(); + } + } + ix++; + } + return checkedOrderTokens; + } + + /** A helper method that 'folds' any columns specified in an order clause + * into the primary key fields so that they can be included in the select + * list <b>after</b> all primary key fields. + */ + private String getExtraOrderColumns(FinderMetaData f) { String strippedOrder = ""; if(f.getOrder()!=null && f.getOrder()!="") { - //Split it into tokens. These tokens might contain ASC/DESC that we have to get rid of - StringTokenizer orderTokens = new StringTokenizer(f.getOrder(), ","); - String orderToken; - String[] checkedOrderTokens = new String[orderTokens.countTokens()]; - int ix = 0; - while(orderTokens.hasMoreTokens()) - { - orderToken = orderTokens.nextToken().trim(); - //Get rid of ASC's - int i = orderToken.toUpperCase().indexOf(" ASC"); - if(i!=-1) - checkedOrderTokens[ix] = orderToken.substring(0, i).trim(); - else - { - //Get rid of DESC's - i = orderToken.toUpperCase().indexOf(" DESC"); - if(i!=-1) - checkedOrderTokens[ix] = orderToken.substring(0, i).trim(); - else - { - //No ASC/DESC - just use it as it is - checkedOrderTokens[ix] = new String(orderToken).trim(); - } - } - ix++; - } - + String[] checkedOrderTokens = cleanOrderClause(f.getOrder()); + //Next step is to make up a Set of all pk tokens StringTokenizer pkTokens = new StringTokenizer(getPkColumnList(), ","); Set setOfPkTokens = new HashSet(pkTokens.countTokens()); @@ -109,7 +206,7 @@ { setOfPkTokens.add(pkTokens.nextToken().trim()); } - + //Now is the time to check for duplicates between pk and order tokens int i = 0; while(i < checkedOrderTokens.length) @@ -121,7 +218,7 @@ } i++; } - + //Ok, build a new order string that we can use later on StringBuffer orderTokensToUse = new StringBuffer(""); i = 0; @@ -136,83 +233,9 @@ } // Note that orderTokensToUse will always start with ", " if there is any order tokens strippedOrder = orderTokensToUse.toString(); - } - - // Construct SQL - // In case of join query: - // order must explicitly identify tablename.field to order on - // query must start with "INNER JOIN <table to join with> WHERE - // <regular query with fully identified fields>" - String sql = null; - if (query.toLowerCase().startsWith(",")) { - //Modified by Vinay Menon - StringBuffer sqlBuffer = new StringBuffer(); - - sqlBuffer.append("SELECT "); - - String primaryKeyList = getPkColumnList(); - String tableName = jawsEntity.getTableName(); - StringTokenizer stok = new StringTokenizer(primaryKeyList,","); - - while(stok.hasMoreTokens()){ - sqlBuffer.append(tableName); - sqlBuffer.append("."); - sqlBuffer.append(stok.nextElement().toString()); - sqlBuffer.append(","); - } - - sqlBuffer.setLength(sqlBuffer.length()-1); - sqlBuffer.append(strippedOrder); - sqlBuffer.append(" FROM "); - sqlBuffer.append(jawsEntity.getTableName()); - sqlBuffer.append(" "); - sqlBuffer.append(query); - - sql = sqlBuffer.toString(); - } else - if (query.toLowerCase().startsWith("inner join")) { - StringBuffer sqlBuffer = new StringBuffer(); - - sqlBuffer.append("SELECT "); - - String primaryKeyList = getPkColumnList(); - String tableName = jawsEntity.getTableName(); - StringTokenizer stok = new StringTokenizer(primaryKeyList,","); - - while(stok.hasMoreTokens()){ - sqlBuffer.append(tableName); - sqlBuffer.append("."); - sqlBuffer.append(stok.nextElement().toString()); - sqlBuffer.append(","); - } - - sqlBuffer.setLength(sqlBuffer.length()-1); - sqlBuffer.append(strippedOrder); - sqlBuffer.append(" FROM "); - sqlBuffer.append(jawsEntity.getTableName()); - sqlBuffer.append(" "); - sqlBuffer.append(query); - - sql = sqlBuffer.toString(); - } else { - // regular query; check if query is empty, - // if so, this is a select all and WHERE should not be used - if (f.getQuery() == null) { - sql = "SELECT " + getPkColumnList() + strippedOrder + - " FROM " + jawsEntity.getTableName(); - } else { - sql = "SELECT " + getPkColumnList() + strippedOrder + - " FROM " + jawsEntity.getTableName() + " WHERE " + query; - } } - if (f.getOrder() != null && !f.getOrder().equals("")) - { - sql += " ORDER BY "+f.getOrder(); - } - - setSQL(sql); - } - + return strippedOrder; + } // JDBCFinderCommand overrides ------------------------------------ protected void setParameters(PreparedStatement stmt, Object argOrArgs) 1.5 +12 -1 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindAllCommand.java Index: JDBCFindAllCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindAllCommand.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- JDBCFindAllCommand.java 2001/05/27 00:49:15 1.4 +++ JDBCFindAllCommand.java 2001/06/13 06:52:17 1.5 @@ -17,7 +17,7 @@ * @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> - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ public class JDBCFindAllCommand extends JDBCFinderCommand { @@ -30,5 +30,16 @@ String sql = "SELECT " + getPkColumnList() + " FROM " + jawsEntity.getTableName(); setSQL(sql); + } + + public String getWhereClause() { + return ""; + } + + public String getFromClause() { + return " FROM " + jawsEntity.getTableName(); + } + public String getOrderByClause() { + return ""; } } 1.9 +15 -1 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindByCommand.java Index: JDBCFindByCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindByCommand.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- JDBCFindByCommand.java 2001/05/27 17:59:00 1.8 +++ JDBCFindByCommand.java 2001/06/13 06:52:17 1.9 @@ -27,7 +27,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a> * @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a> * @author <a href="mailto:[EMAIL PROTECTED]">danch (Dan Christopherson)</a> - * @version $Revision: 1.8 $ + * @version $Revision: 1.9 $ */ public class JDBCFindByCommand extends JDBCFinderCommand { @@ -75,6 +75,20 @@ sql += cmpField.getColumnName() + "=?"; setSQL(sql); + } + + // JDBCQueryCommand overrides + + public String getWhereClause() { + return cmpField.getColumnName() + "=?"; + } + + public String getFromClause() { + return " FROM "+jawsEntity.getTableName(); + } + + public String getOrderByClause() { + return ""; } // JDBCFinderCommand overrides ----------------------------------- 1.11 +19 -1 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFinderCommand.java Index: JDBCFinderCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFinderCommand.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- JDBCFinderCommand.java 2001/05/27 00:49:15 1.10 +++ JDBCFinderCommand.java 2001/06/13 06:52:17 1.11 @@ -35,7 +35,7 @@ * @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> - * @version $Revision: 1.10 $ + * @version $Revision: 1.11 $ */ public abstract class JDBCFinderCommand extends JDBCQueryCommand @@ -55,6 +55,24 @@ return finderMetaData; } + + /** This method must be overridden to return the where clause used in + * this query. This must start with the keyword 'WHERE' and include all + * conditions needed to execute the query properly. + */ + public abstract String getWhereClause(); + + /** This method must be ovverridden to return the full table list for + * the query, including any join statements. This must start with the + * keyword 'FROM' and include all tables needed to execute the query properly. + */ + public abstract String getFromClause(); + + /** This method must be ovverridded to return the full order by clause for + * the query, including the 'ORDER BY' keyword. + */ + public abstract String getOrderByClause(); + // JPMFindEntitiesCommand implementation ------------------------- public FinderResults execute(Method finderMethod, 1.2 +35 -16 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntitiesCommand.java Index: JDBCLoadEntitiesCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntitiesCommand.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- JDBCLoadEntitiesCommand.java 2001/05/27 00:49:15 1.1 +++ JDBCLoadEntitiesCommand.java 2001/06/13 06:52:17 1.2 @@ -19,6 +19,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import org.jboss.ejb.EntityEnterpriseContext; import org.jboss.ejb.plugins.jaws.JAWSPersistenceManager; @@ -30,7 +31,8 @@ import org.jboss.util.FinderResults; /** - * JAWSPersistenceManager JDBCLoadEntityCommand + * Implementation of the LoadEntitiesCommand added in JBoss 2.3. This preloads + * data for all entities whose keys were retrieved by a finder. * * @see <related> * @author <a href="mailto:[EMAIL PROTECTED]">Rickard Öberg</a> @@ -39,7 +41,7 @@ * @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.1 $ + * @version $Revision: 1.2 $ */ public class JDBCLoadEntitiesCommand extends JDBCLoadEntityCommand @@ -86,23 +88,39 @@ while (rs.next()) { Object key = createKey(rs); - - //find the context - EntityEnterpriseContext ctx = (EntityEnterpriseContext)instances.get(key); - if (ctx != null) { - //if the context says it's already valid, don't load it. - if (!ctx.isValid()) { - loadOneEntity(rs, ctx); - ctx.setValid(true); - } - } else { - //if ctx was null, the CMPPersistenceManager doesn't want us to try - // to load it due to a transaction issue. - } + preloadOneEntity(rs, key); } return null; } + protected void preloadOneEntity(ResultSet rs, Object key) { +//log.debug("PRELOAD: preloading entity "+key); + int idx = 1; + // skip the PK fields at the beginning of the select. + Iterator keyIt = jawsEntity.getPkFields(); + while (keyIt.hasNext()) { + keyIt.next(); + idx++; + } + + int fieldCount = 0; + Object[] allValues = new Object[jawsEntity.getNumberOfCMPFields()]; + Iterator iter = jawsEntity.getCMPFields(); + try { + while (iter.hasNext()) + { + CMPFieldMetaData cmpField = (CMPFieldMetaData)iter.next(); + + Object value = getResultObject(rs, cmpFieldPositionInSelect[fieldCount], cmpField); + allValues[fieldCount] = value; + fieldCount++; + } + factory.addPreloadData(key, allValues); + } catch (SQLException sqle) { + log.warning("SQL Error preloading data for key "+key); + } + } + protected void setParameters(PreparedStatement stmt, Object argOrArgs) throws Exception { @@ -116,7 +134,8 @@ protected String getSQL(Object argOrArgs) throws Exception { FinderResults keys = (FinderResults)((Object[])argOrArgs)[0]; - return selectClause + " " + keys.getQueryData().toString(); + JDBCFinderCommand finder = (JDBCFinderCommand)keys.getFinder(); + return selectClause + " " + finder.getFromClause() + " " + finder.getWhereClause() + " " + finder.getOrderByClause(); } // protected ----------------------------------------------------- 1.11 +38 -9 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntityCommand.java Index: JDBCLoadEntityCommand.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntityCommand.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- JDBCLoadEntityCommand.java 2001/06/06 01:07:40 1.10 +++ JDBCLoadEntityCommand.java 2001/06/13 06:52:17 1.11 @@ -39,7 +39,7 @@ * @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.10 $ + * @version $Revision: 1.11 $ */ public class JDBCLoadEntityCommand extends JDBCQueryCommand @@ -66,7 +66,8 @@ { super(factory, "Load"); - String sql = createSelectClause() + " WHERE " + getPkColumnWhereList(); + String sql = createSelectClause() + " FROM " + jawsEntity.getTableName() + + " WHERE " + getPkColumnWhereList(); if (jawsEntity.hasSelectForUpdate()) { sql += " FOR UPDATE"; @@ -89,7 +90,8 @@ { PkFieldMetaData pkField = (PkFieldMetaData)keyIt.next(); - sql += ((fieldCount==0) ? "" : ",") + pkField.getColumnName(); + sql += ((fieldCount==0) ? "" : ",") + + jawsEntity.getTableName() + "." + pkField.getColumnName(); alreadyListed.put(pkField.getColumnName().toUpperCase(), pkField); pkColumnNames[fieldCount]=pkField.getColumnName(); fieldCount++; @@ -102,7 +104,7 @@ { CMPFieldMetaData cmpField = (CMPFieldMetaData)it.next(); if (alreadyListed.get(cmpField.getColumnName().toUpperCase()) == null) { - sql += "," + cmpField.getColumnName(); + sql += "," + jawsEntity.getTableName() + "." + cmpField.getColumnName(); cmpFieldPositionInSelect[cmpFieldCount] = fieldCount+JDBC_WART_OFFSET; fieldCount++;//because this was another field in the select } else { @@ -123,8 +125,8 @@ cmpFieldCount++; } - sql += " FROM " + jawsEntity.getTableName(); + return sql; } @@ -137,7 +139,13 @@ { try { - jdbcExecute(ctx); + //first check to see if the data was preloaded + Object[] data = factory.getPreloadData(ctx.getId()); + if (data != null) { + loadFromPreload(data, ctx); + } else { + jdbcExecute(ctx); + } } catch (Exception e) { throw new ServerException("Load failed", e); @@ -170,7 +178,28 @@ return null; } - protected void loadOneEntity(ResultSet rs, EntityEnterpriseContext ctx) throws Exception { + protected void loadFromPreload(Object[] data, EntityEnterpriseContext ctx) throws Exception { +//log.debug("PRELOAD: Loading from preload - entity "+ctx.getId()); + int fieldCount = 0; + Iterator iter = jawsEntity.getCMPFields(); + while (iter.hasNext()) + { + CMPFieldMetaData cmpField = (CMPFieldMetaData)iter.next(); + + setCMPFieldValue(ctx.getInstance(), + cmpField, + data[fieldCount]); + fieldCount++; + } + + // Store state to be able to do tuned updates + JAWSPersistenceManager.PersistenceContext pCtx = + (JAWSPersistenceManager.PersistenceContext)ctx.getPersistenceContext(); + if (jawsEntity.isReadOnly()) pCtx.lastRead = System.currentTimeMillis(); + pCtx.state = getState(ctx); + } + + protected void loadOneEntity(ResultSet rs, EntityEnterpriseContext ctx) throws Exception { int idx = 1; // skip the PK fields at the beginning of the select. Iterator keyIt = jawsEntity.getPkFields(); @@ -185,8 +214,8 @@ { CMPFieldMetaData cmpField = (CMPFieldMetaData)iter.next(); - setCMPFieldValue(ctx.getInstance(), - cmpField, + setCMPFieldValue(ctx.getInstance(), + cmpField, getResultObject(rs, cmpFieldPositionInSelect[fieldCount], cmpField)); fieldCount++; } _______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] http://lists.sourceforge.net/lists/listinfo/jboss-development