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

Reply via email to