db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b..@apache.org
Subject cvs commit: jakarta-ojb/src/java/org/apache/ojb/broker/singlevm PersistenceBrokerImpl.java
Date Sun, 08 Dec 2002 13:28:45 GMT
brj         2002/12/08 05:28:45

  Modified:    src/java/org/apache/ojb/broker/singlevm
                        PersistenceBrokerImpl.java
  Log:
  improved handling for m:n indirection table
  
  Revision  Changes    Path
  1.88      +158 -30   jakarta-ojb/src/java/org/apache/ojb/broker/singlevm/PersistenceBrokerImpl.java
  
  Index: PersistenceBrokerImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/singlevm/PersistenceBrokerImpl.java,v
  retrieving revision 1.87
  retrieving revision 1.88
  diff -u -r1.87 -r1.88
  --- PersistenceBrokerImpl.java	1 Dec 2002 11:47:20 -0000	1.87
  +++ PersistenceBrokerImpl.java	8 Dec 2002 13:28:44 -0000	1.88
  @@ -537,8 +537,6 @@
                       Object col = cds.getPersistentField().get(obj);
                       if (col != null)
                       {
  -                        //logger.info("DELETING collection for "+obj);
  -                        //logger.info("DELETING collection "+cds.getItemClass()+"="+col);
   
                           if (col instanceof ManageableCollection)
                           {
  @@ -733,19 +731,22 @@
           {
               CollectionDescriptor cds = (CollectionDescriptor) i.next();
               Object col = cds.getPersistentField().get(obj);
  -
  -            if (cds.isMtoNRelation())
  -            {
  -                /* LEANDRO
  -				 * Clear all MtoN implementors.
  -				 * All new MtoN implementors are going to be added bellow
  -				 */
  -                //logger.info("STORE COLLECTIONS: deleting all MtoN implementors for field
"+cds.getPersistentField().getName());
  -                deleteMtoNImplementor(cds, obj);
  -            }
  -
  +            Collection currentMtoNKeys = null;
  +            
               if (col != null)
               {
  +                if (cds.isMtoNRelation())
  +                {
  +                    currentMtoNKeys = getMtoNImplementor(cds, obj);
  +
  +                    /* LEANDRO
  +                     * Clear all MtoN implementors.
  +                     * All new MtoN implementors are going to be added bellow
  +                     */
  +                    deleteMtoNImplementor(cds, obj, (Collection)col, currentMtoNKeys);
  +                }
  +
  +
                   // MBAIRD
                   // if the collection is a collectionproxy and it's not already loaded
                   // no need to store it.
  @@ -782,7 +783,7 @@
                           // 1. Store depended upon object first to avoid FK violation
                           storeCollectionObject(cds, otherObj, markedForStore);
                           // 2. Store indirection record
  -                        storeMtoNImplementor(cds, obj, otherObj);
  +                        storeMtoNImplementor(cds, obj, otherObj, currentMtoNKeys);
                       }
                       // for 1:n mapped collection assert proper fk assignment
                       else
  @@ -808,32 +809,32 @@
           // if cascade store: store associated object
           if (cds.getCascadeStore())
           {
  -            //logger.info("STORING collection object "+cds.getItemClass()+"="+otherObject);
  -
               store(otherObject, markedForStore);
           }
       }
   
       /**
  -     * This method is used to store values of a M:N association in a indirection table.
  -
  +     * This method is used to store values of a M:N association in a indirection
  +     * table.
        */
  -    private void storeMtoNImplementor(CollectionDescriptor cod, Object obj, Object otherObj)
  +    private void storeMtoNImplementor(CollectionDescriptor cod, Object obj, Object otherObj,
Collection mnKeys)
       {
           ClassDescriptor cld = getDescriptorRepository().getDescriptorFor(obj.getClass());
  -        Object[] pkValues = cld.getKeyValues(obj);
  +        Object[] pkValues = cld.getKeyValues(obj);      
           Object[] pkColumns = cod.getFksToThisClass();
           ClassDescriptor otherCld = getDescriptorRepository().getDescriptorFor(otherObj.getClass());
           Object[] otherPkValues = otherCld.getKeyValues(otherObj);
           Object[] otherPkColumns = cod.getFksToItemClass();
  -        Object[] values = new Object[pkValues.length + otherPkValues.length];
  -        System.arraycopy(pkValues, 0, values, 0, pkValues.length);
  -        System.arraycopy(otherPkValues, 0, values, pkValues.length, otherPkValues.length);
  -        Object[] columns = new Object[pkColumns.length + otherPkColumns.length];
  -        System.arraycopy(pkColumns, 0, columns, 0, pkColumns.length);
  -        System.arraycopy(otherPkColumns, 0, columns, pkColumns.length, otherPkColumns.length);
           String table = cod.getIndirectionTable();
  -        String insertStmt = sqlGenerator.getInsertStatement(table, columns, values);
  +        Key key = new Key(otherPkValues);
  +
  +        if (mnKeys.contains(key))
  +        {
  +            return;
  +        }    
  +                
  +        String insertStmt = sqlGenerator.getInsertStatement(table, pkColumns, pkValues
,otherPkColumns ,otherPkValues);
  +
           try
           {
               dbAccess.executeUpdateSQL(insertStmt, cld);
  @@ -844,13 +845,53 @@
           }
       }
   
  +    /**
  +     * get a Collection of Keys of already existing m:n rows
  +     * @param cod
  +     * @param obj
  +     * @return Collection of Key
  +     */
  +    private Collection getMtoNImplementor(CollectionDescriptor cod, Object obj)
  +    {
  +        ResultSetAndStatement rs;
  +        List result = new ArrayList();
  +        ClassDescriptor cld = getDescriptorRepository().getDescriptorFor(obj.getClass());
  +        Object[] pkValues = cld.getKeyValues(obj);
  +        Object[] pkColumns = cod.getFksToThisClass();
  +        Object[] fkColumns = cod.getFksToItemClass();
  +        String table = cod.getIndirectionTable();
  +        String selectStmt = sqlGenerator.getSelectStatement(table, fkColumns, pkColumns,
pkValues);
  +        
  +        try
  +        {
  +            rs = dbAccess.executeSQL(selectStmt, cld);
  +            while (rs.m_rs.next())
  +            {
  +                Object[] row = new Object[fkColumns.length];
  +                for (int i = 0; i < row.length; i++)
  +                {
  +                    row[i] = rs.m_rs.getObject(i + 1);
  +                }  
  +                result.add(new Key(row));  
  +            }    
  +            rs.m_rs.close();
  +            rs.m_stmt.close();
  +        }
  +        catch (Exception e)
  +        {
  +            throw new PersistenceBrokerException(e);
  +        } 
  +
  +        return result;
  +    }
  +  
       private void deleteMtoNImplementor(CollectionDescriptor cod, Object obj)
       {
           ClassDescriptor cld = getDescriptorRepository().getDescriptorFor(obj.getClass());
           Object[] pkValues = cld.getKeyValues(obj);
           Object[] pkColumns = cod.getFksToThisClass();
           String table = cod.getIndirectionTable();
  -        String deleteStmt = sqlGenerator.getDeleteStatement(table, pkColumns, pkValues);
  +        String deleteStmt = sqlGenerator.getDeleteStatement(table, pkColumns, pkValues,
null ,null);
           try
           {
               dbAccess.executeUpdateSQL(deleteStmt, cld);
  @@ -861,7 +902,56 @@
               // attempts to del existing entries are ignored
           }
       }
  -
  +  
  +    /**
  +     * deletes all rows from m:n table that are not used in relatedObjects
  +     * @param cod
  +     * @param obj
  +     * @param relatedObjects
  +     * @param mnKeys
  +     */
  +    private void deleteMtoNImplementor(CollectionDescriptor cod, Object obj, Collection
relatedObjects, Collection mnKeys)
  +    {
  +        if (mnKeys.isEmpty() || relatedObjects == null)
  +        {
  +            return;
  +        }    
  +            
  +        List workList = new ArrayList(mnKeys);
  +        Iterator iter;
  +        Key relatedObjKeys;
  +        ClassDescriptor relatedCld = getDescriptorRepository().getDescriptorFor(cod.getItemClass());
  +        Object relatedObj;
  +     
  +		// remove keys of relatedObject from the existing m:n rows in workList
  +		iter = relatedObjects.iterator();
  +
  +		while (iter.hasNext())
  +		{
  +			relatedObj = iter.next();
  +			relatedObjKeys = new Key(relatedCld.getKeyValues(relatedObj, true));
  +			workList.remove(relatedObjKeys);
  +		}
  +	    
  +        // delete all remaining keys in workList 
  +        ClassDescriptor cld = getDescriptorRepository().getDescriptorFor(obj.getClass());
  +        Object[] pkValues = cld.getKeyValues(obj);
  +        Object[] pkColumns = cod.getFksToThisClass();
  +        Object[] fkValues;
  +        Object[] fkColumns = cod.getFksToItemClass();
  +        String table = cod.getIndirectionTable();
  +        String deleteStmt;
  +        
  +        iter = workList.iterator();
  +        while (iter.hasNext())
  +        {
  +            fkValues = ((Key)iter.next()).m_key;
  +            deleteStmt = sqlGenerator.getDeleteStatement(table, pkColumns, pkValues, fkColumns,
fkValues);
  +            dbAccess.executeUpdateSQL(deleteStmt, cld);
  +        }
  +        
  +    }
  +      
       /**
        * retrieve all References (also Collection-attributes) of a given instance.
        * Loading is forced, even if the collection- and reference-descriptors differ.
  @@ -2577,4 +2667,42 @@
           }
       }
   
  +    /**
  +     * This is a helper class to model a Key of an Object
  +     */
  +    private class Key
  +    {
  +        Object[] m_key;
  +        
  +        Key(Object[] aKey)
  +        {
  +            m_key = aKey;
  +        }    
  +        
  +        public boolean equals(Object otherKey)
  +        {
  +            boolean result = false;
  +            
  +            if (otherKey instanceof Key)
  +            {
  +                Key k = (Key)otherKey;
  +                
  +                if (k.m_key.length == m_key.length)
  +                {
  +                    for (int i= 0;i < m_key.length; i++)
  +                    {
  +                        if (k.m_key[i].equals(m_key[i]))
  +                        {
  +                            result = true;
  +                        }    
  +                        else
  +                        {
  +                            break;
  +                        }    
  +                    }   
  +                }   
  +            }    
  +            return result;
  +        }    
  +    }    
   }
  
  
  

Mime
View raw message