db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/src/java/org/apache/ojb/broker/accesslayer StatementManager.java
Date Fri, 19 Dec 2003 17:38:13 GMT
arminw      2003/12/19 09:38:13

  Modified:    src/test/org/apache/ojb/broker/metadata Tag: OJB_BRANCH_1_0
                        MetadataTest.java MetadataMultithreadedTest.java
               src/java/org/apache/ojb/broker/metadata Tag: OJB_BRANCH_1_0
                        RepositoryXmlHandler.java MetadataManager.java
                        DescriptorRepository.java ClassDescriptor.java
               src/java/org/apache/ojb/broker/core Tag: OJB_BRANCH_1_0
                        PersistenceBrokerImpl.java
               src/java/org/apache/ojb/broker/accesslayer Tag:
                        OJB_BRANCH_1_0 StatementManager.java
  Log:
  - fix major bug when using per thread metadata changes
  (memory leak when associate each thread with different descriptor repository)
  
  - take care of side-effects when changing metadata made in
  DescriptorRepository or ClassDescriptor
  (add ClassDescriptor, ClassDescriptor add FieldDescriptor)
  
  - add new test cases to verify made changes
  
  (synchronize with changes made in trunk)
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.13.2.1  +70 -5     db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataTest.java
  
  Index: MetadataTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataTest.java,v
  retrieving revision 1.13
  retrieving revision 1.13.2.1
  diff -u -r1.13 -r1.13.2.1
  --- MetadataTest.java	9 Dec 2003 13:46:47 -0000	1.13
  +++ MetadataTest.java	19 Dec 2003 17:38:13 -0000	1.13.2.1
  @@ -1,15 +1,17 @@
   package org.apache.ojb.broker.metadata;
   
  +import java.util.Iterator;
  +
   import junit.framework.TestCase;
  +import org.apache.ojb.broker.Identity;
  +import org.apache.ojb.broker.ObjectRepository;
   import org.apache.ojb.broker.PBKey;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.PersistenceBrokerFactory;
   import org.apache.ojb.broker.TestHelper;
  -import org.apache.ojb.broker.ObjectRepository;
  -import org.apache.ojb.broker.Identity;
  -import org.apache.ojb.broker.cache.ObjectCacheEmptyImpl;
   import org.apache.ojb.broker.cache.ObjectCacheDefaultImpl;
  +import org.apache.ojb.broker.cache.ObjectCacheEmptyImpl;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.query.QueryFactory;
  @@ -21,8 +23,6 @@
   import org.odmg.OQLQuery;
   import org.odmg.Transaction;
   
  -import java.util.Iterator;
  -
   /**
    * This TestClass tests the RepositoryPersitors facilities for
    * reading and writing a valid repository.
  @@ -62,6 +62,71 @@
           catch (Exception e)
           {
           }
  +    }
  +
  +    public void testDescriptorRepository_1()
  +    {
  +        MetadataManager mm = MetadataManager.getInstance();
  +        DescriptorRepository dr = mm.copyOfGlobalRepository();
  +        // get an class/interface with extents
  +        ClassDescriptor cld = dr.getDescriptorFor(Repository.SMMax.class);
  +
  +        int extentSize = cld.getExtentClasses().size();
  +        Class topLevelInterface = dr.getTopLevelClass(Repository.SMMax.class);
  +        Class topLevelExtent = dr.getTopLevelClass(Repository.SMMaxA.class);
  +        assertEquals(Repository.SMMax.class, topLevelInterface);
  +        assertEquals(Repository.SMMax.class, topLevelExtent);
  +        assertEquals(2, extentSize);
  +
  +        dr.removeExtent(Repository.SMMaxA.class.getName());
  +        int extentSizeNew = cld.getExtentClasses().size();
  +        Class topLevelInterfaceNew = dr.getTopLevelClass(Repository.SMMax.class);
  +        Class topLevelExtentNew = dr.getTopLevelClass(Repository.SMMaxA.class);
  +        assertEquals(Repository.SMMax.class, topLevelInterfaceNew);
  +        assertEquals(Repository.SMMaxA.class, topLevelExtentNew);
  +        assertEquals(1, extentSizeNew);
  +    }
  +
  +    public void testDescriptorRepository_2()
  +    {
  +        MetadataManager mm = MetadataManager.getInstance();
  +        DescriptorRepository dr = mm.copyOfGlobalRepository();
  +        // get an class/interface with extents
  +        ClassDescriptor cld = dr.getDescriptorFor(Repository.SMMax.class);
  +        int allSubClasses = dr.getAllConcreteSubclassDescriptors(cld).size();
  +        int allExtents = cld.getExtentClasses().size();
  +        int allExtentNames = cld.getExtentClassNames().size();
  +        assertEquals(allExtents, allExtentNames);
  +
  +        dr.remove(Repository.SMMaxA.class);
  +        // after removing SMMaxA, SMMax interface lost 4 concrete extents (sub-classes)
  +        // be carefully in changing SMM*** metadata, could make fail this test
  +        int allSubClassesNew = dr.getAllConcreteSubclassDescriptors(cld).size();
  +        int allExtentsNew = cld.getExtentClasses().size();
  +        int allExtentNamesNew = cld.getExtentClassNames().size();
  +        assertEquals(allExtentsNew, allExtentNamesNew);
  +        assertEquals(allSubClasses - 4, allSubClassesNew);
  +    }
  +
  +    public void testClassDescriptor_1()
  +    {
  +        MetadataManager mm = MetadataManager.getInstance();
  +        DescriptorRepository dr = mm.copyOfGlobalRepository();
  +        ClassDescriptor cld = dr.getDescriptorFor(ObjectRepository.Component.class);
  +
  +        FieldDescriptor[] a = cld.getAutoIncrementFields();
  +        assertEquals("autoincrement field should be found", 1, a.length);
  +        FieldDescriptor target = cld.getFieldDescriptorByName("id");
  +        cld.removeFieldDescriptor(target);
  +        a = cld.getAutoIncrementFields();
  +        assertEquals("autoincrement PK should be deleted", 0, a.length);
  +        assertNull(cld.getFieldDescriptorByName("id"));
  +
  +        cld.addFieldDescriptor(target);
  +        a = cld.getAutoIncrementFields();
  +        assertEquals("autoincrement field should be found", 1, a.length);
  +        assertNotNull(cld.getFieldDescriptorByName("id"));
  +
       }
   
       public void testLoadingProfiles() throws Exception
  
  
  
  1.3.2.1   +81 -23    db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataMultithreadedTest.java
  
  Index: MetadataMultithreadedTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataMultithreadedTest.java,v
  retrieving revision 1.3
  retrieving revision 1.3.2.1
  diff -u -r1.3 -r1.3.2.1
  --- MetadataMultithreadedTest.java	9 Aug 2003 13:23:40 -0000	1.3
  +++ MetadataMultithreadedTest.java	19 Dec 2003 17:38:13 -0000	1.3.2.1
  @@ -4,7 +4,13 @@
   import org.apache.ojb.broker.OJBRuntimeException;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerFactory;
  +import org.apache.ojb.broker.util.ClassHelper;
  +import org.apache.ojb.broker.query.Criteria;
  +import org.apache.ojb.broker.query.Query;
  +import org.apache.ojb.broker.query.QueryByCriteria;
   import org.apache.ojb.broker.sequence.Repository;
  +import org.apache.ojb.odmg.PersonImpl;
  +import org.apache.commons.lang.ClassUtils;
   
   /**
    *
  @@ -13,10 +19,13 @@
    */
   public class MetadataMultithreadedTest extends JUnitExtensions.MultiThreadedTestCase
   {
  -    private String newTestObjectString = "test_string";
  -    private String oldTestObjectString;
  +    // we change table name in test for target class
  +    private String newTestObjectString = "SM_TAB_MAX_AA";
       private Class targetTestClass = Repository.SMMaxA.class;
   
  +    private String oldTestObjectString;
  +    DescriptorRepository defaultRepository;
  +
       public MetadataMultithreadedTest(String s)
       {
           super(s);
  @@ -46,39 +55,69 @@
   
       public void testRuntimeMetadataChanges() throws Exception
       {
  -        int loops = 10;
  +        int loops = 5;
  +        int threads = 5;
           PersistenceBroker broker = null;
           try
           {
  +            MetadataManager mm = MetadataManager.getInstance();
               // enable the per thread changes of metadata
  -            MetadataManager.getInstance().setEnablePerThreadChanges(true);
  +            mm.setEnablePerThreadChanges(true);
  +            defaultRepository = mm.copyOfGlobalRepository();
  +            mm.setDescriptor(defaultRepository);
   
               ClassDescriptor cld;
   
               try
               {
  +                // prepare for test
                   long period = System.currentTimeMillis();
                   broker = PersistenceBrokerFactory.defaultPersistenceBroker();
                   cld = broker.getClassDescriptor(targetTestClass);
   
                   // we manipulate the schema name of the class
                   // thus we note the original value
  -                oldTestObjectString = cld.getSchema();
  +                oldTestObjectString = cld.getFullTableName();
                   broker.close();
   
  -                TestCaseRunnable tct [] = new TestCaseRunnable[10];
  -                for (int i = 0; i < 10; i++)
  +                // cleanup JVM
  +                Runtime.getRuntime().gc();
  +                Thread.sleep(200);
  +                Runtime.getRuntime().gc();
  +
  +                // start test
  +                long memory = Runtime.getRuntime().freeMemory();
  +                long totalMemory = Runtime.getRuntime().maxMemory();
  +                int count = 0;
  +                for (int k = 0; k < loops; k++)
                   {
  -                    if (i < 5)
  -                        tct[i] = new ThreadedUsingBroker(loops);
  -                    else
  -                        tct[i] = new GlobalUsingBroker(loops);
  +                    TestCaseRunnable tct [] = new TestCaseRunnable[threads];
  +                    for (int i = 0; i < threads; i++)
  +                    {
  +                        if (i % 2 == 0)
  +                            tct[i] = new ThreadedUsingBroker(loops);
  +                        else
  +                            tct[i] = new GlobalUsingBroker(loops);
  +                    }
  +                    // run test classes
  +                    runTestCaseRunnables(tct);
  +                    ++count;
  +                    System.out.println("Free/total Memory after loop " + count + ":   
      "
  +                            + convertToMB(Runtime.getRuntime().freeMemory())
  +                            + "/" + convertToMB(Runtime.getRuntime().maxMemory()) + "MB");
                   }
  -                // run test classes
  -                runTestCaseRunnables(tct);
  -
                   period = System.currentTimeMillis() - period;
  -                System.out.println("RuntimeMetadataChanges test take: " + period + " ms");
  +                System.out.println(ClassUtils.getShortClassName(MetadataMultithreadedTest.class)
+ " take: "
  +                        + period + " ms for " + loops + " loops, creating each with " +
threads + " threads");
  +                System.out.println("Free/total Memory before test:          "
  +                        + convertToMB(memory) + "/" + convertToMB(totalMemory) + "MB");
  +                Runtime.getRuntime().gc();
  +                Thread.sleep(200);
  +                Runtime.getRuntime().gc();
  +                System.out.println("Free/total Memory after test after gc:   "
  +                        + convertToMB(Runtime.getRuntime().freeMemory())
  +                        + "/" + convertToMB(Runtime.getRuntime().maxMemory()) + "MB");
  +                System.out.println("Do cleanup now ...");
               }
               finally
               {
  @@ -87,7 +126,7 @@
   
               broker = PersistenceBrokerFactory.defaultPersistenceBroker();
               cld = broker.getClassDescriptor(targetTestClass);
  -            String name = cld.getSchema();
  +            String name = cld.getFullTableName();
               assertEquals(oldTestObjectString, name);
               assertFalse(MetadataManager.getInstance().isEnablePerThreadChanges());
           }
  @@ -97,6 +136,11 @@
           }
       }
   
  +    private long convertToMB(long byteValue)
  +    {
  +        return (byteValue / 1024) / 1024;
  +    }
  +
       // ======================================================================
       // inner test class
       // ======================================================================
  @@ -113,13 +157,13 @@
               this.loops = loops;
           }
   
  -        public void runTestCase()
  +        public void runTestCase() throws Exception
           {
               MetadataManager mm = MetadataManager.getInstance();
               DescriptorRepository dr = mm.copyOfGlobalRepository();
               ClassDescriptor cld = dr.getDescriptorFor(targetTestClass);
               // we change a class descriptor value
  -            cld.setSchema(newTestObjectString);
  +            cld.setTableName(newTestObjectString);
               // set the changed repository for this thread
               mm.setDescriptor(dr);
   
  @@ -131,7 +175,7 @@
                   {
                       broker = PersistenceBrokerFactory.defaultPersistenceBroker();
                       cld = broker.getClassDescriptor(targetTestClass);
  -                    String name = cld.getSchema();
  +                    String name = cld.getFullTableName();
                       assertEquals(newTestObjectString, name);
                       assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
                   }
  @@ -143,10 +187,23 @@
                   try
                   {
                       broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  +                    // check made changes
                       cld = broker.getClassDescriptor(targetTestClass);
  -                    String name = cld.getSchema();
  +                    String name = cld.getFullTableName();
                       assertEquals(newTestObjectString, name);
                       assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
  +                    // query the object
  +                    Query query = new QueryByCriteria(PersonImpl.class, (Criteria) null,
true);
  +                    broker.getCollectionByQuery(query);
  +                    // store target object
  +                    Object obj = ClassHelper.newInstance(targetTestClass);
  +                    broker.beginTransaction();
  +                    broker.store(obj);
  +                    broker.commitTransaction();
  +                    // delete target object
  +                    broker.beginTransaction();
  +                    broker.delete(obj);
  +                    broker.commitTransaction();
                   }
                   finally
                   {
  @@ -188,10 +245,11 @@
                   {
                       try
                       {
  +                        MetadataManager.getInstance().setDescriptor(defaultRepository);
                           broker = PersistenceBrokerFactory.defaultPersistenceBroker();
                           ClassDescriptor cld = broker.getClassDescriptor(targetTestClass);
                           assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
  -                        String name = cld.getSchema();
  +                        String name = cld.getFullTableName();
                           // this PB instance use unchanged global metadata repository
                           assertEquals(getTestObjectString(), name);
                       }
  @@ -204,7 +262,7 @@
                           broker = PersistenceBrokerFactory.defaultPersistenceBroker();
                           ClassDescriptor cld = broker.getClassDescriptor(targetTestClass);
                           assertTrue(MetadataManager.getInstance().isEnablePerThreadChanges());
  -                        String name = cld.getSchema();
  +                        String name = cld.getFullTableName();
                           // this PB instance use unchanged global metadata repository
                           assertEquals(getTestObjectString(), name);
                           // System.out.println("Default: found "+name);
  
  
  
  No                   revision
  No                   revision
  1.50.2.1  +3 -3      db-ojb/src/java/org/apache/ojb/broker/metadata/RepositoryXmlHandler.java
  
  Index: RepositoryXmlHandler.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/RepositoryXmlHandler.java,v
  retrieving revision 1.50
  retrieving revision 1.50.2.1
  diff -u -r1.50 -r1.50.2.1
  --- RepositoryXmlHandler.java	6 Dec 2003 15:54:56 -0000	1.50
  +++ RepositoryXmlHandler.java	19 Dec 2003 17:38:13 -0000	1.50.2.1
  @@ -367,7 +367,7 @@
                       {
                           String classname = atts.getValue("class-ref");
                           if (isDebug) logger.debug("     " + tags.getTagById(CLASS_EXTENT)
+ ": " + classname);
  -                        m_CurrentCLD.addExtentClassName(classname);
  +                        m_CurrentCLD.addExtentClass(classname);
                           break;
                       }
   
  @@ -792,7 +792,7 @@
                               if (className != null)
                               {
                                   if (isDebug) logger.debug("     " + "class" + ": " + className);
  -                                queryCust = (QueryCustomizer)ClassHelper.getClass(className).newInstance();
  +                                queryCust = (QueryCustomizer)ClassHelper.newInstance(className);
                                   m_CurrentAttrContainer = queryCust;
                                   m_CurrentCOD.setQueryCustomizer(queryCust);
                               }
  
  
  
  1.12.2.1  +21 -4     db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java
  
  Index: MetadataManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java,v
  retrieving revision 1.12
  retrieving revision 1.12.2.1
  diff -u -r1.12 -r1.12.2.1
  --- MetadataManager.java	28 Oct 2003 21:18:47 -0000	1.12
  +++ MetadataManager.java	19 Dec 2003 17:38:13 -0000	1.12.2.1
  @@ -74,7 +74,7 @@
    *   // set the changed repository for this thread
    *   mm.setDescriptor(dr);
    *
  - *   // now this thread could lookup a PersistenceBroker instance
  + *   // now let this thread lookup a PersistenceBroker instance
    *   // with the modified metadata
    *   // all other threads use the global metadata
    *   PersistenceBroker broker = Persis......
  @@ -106,6 +106,8 @@
   {
       private static Logger log = LoggerFactory.getLogger(MetadataManager.class);
   
  +    private static final String MSG_STR = "* Can't find DescriptorRepository for current
thread, use default one *";
  +
       private static ThreadLocal threadedRepository = new ThreadLocal();
       private static MetadataManager singleton = new MetadataManager();
   
  @@ -161,7 +163,7 @@
        * {@link org.apache.ojb.broker.metadata.DescriptorRepository}.
        * <br>
        * When {@link #isEnablePerThreadChanges per thread descriptor handling}  is enabled
  -     * we first search for a specific {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  +     * it search for a specific {@link org.apache.ojb.broker.metadata.DescriptorRepository}
        * for the calling thread, if none can be found the global descriptor was returned.
        *
        * @see MetadataManager#getGlobalRepository
  @@ -176,8 +178,15 @@
               if (repository == null)
               {
                   repository = getGlobalRepository();
  -                log.info("Can't find DescriptorRepository for current thread, use default
one");
  +                log.info(MSG_STR);
               }
  +// arminw:
  +// TODO: Be more strict in per thread mode and throw a exception when not find descriptor
for calling thread?
  +//            if (repository == null)
  +//            {
  +//                throw new MetadataException("Can't find a DescriptorRepository for current
thread, don't forget" +
  +//                        " to set a DescriptorRepository if enable per thread changes
before perform other action");
  +//            }
               return repository;
           }
           else
  @@ -472,6 +481,14 @@
       public DescriptorRepository removeProfile(Object key)
       {
           return (DescriptorRepository) metadataProfiles.remove(key);
  +    }
  +
  +    /**
  +     * Remove all metadata profiles.
  +     */
  +    public void clearProfiles()
  +    {
  +        metadataProfiles.clear();
       }
   
       /**
  
  
  
  1.41.2.1  +97 -19    db-ojb/src/java/org/apache/ojb/broker/metadata/DescriptorRepository.java
  
  Index: DescriptorRepository.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/DescriptorRepository.java,v
  retrieving revision 1.41
  retrieving revision 1.41.2.1
  diff -u -r1.41 -r1.41.2.1
  --- DescriptorRepository.java	9 Dec 2003 17:19:58 -0000	1.41
  +++ DescriptorRepository.java	19 Dec 2003 17:38:13 -0000	1.41.2.1
  @@ -63,7 +63,6 @@
   import java.util.List;
   import java.util.Map;
   import java.util.Set;
  -import java.util.Vector;
   
   import org.apache.commons.lang.SystemUtils;
   import org.apache.commons.lang.builder.ToStringBuilder;
  @@ -107,8 +106,9 @@
        * evaluation, we use this tiny hash map.
        */
       private Map extentTable;
  -    private Map m_multiMappedTableMap;
  -    private Map m_extentClassTable;
  +
  +    private transient Map m_multiMappedTableMap;
  +    private transient Map m_topLevelClassTable;
   
       /**
        * Constructor declaration
  @@ -116,8 +116,6 @@
       public DescriptorRepository() throws PersistenceBrokerException
       {
           descriptorTable = new HashMap();
  -        m_multiMappedTableMap = new HashMap();
  -        m_extentClassTable = new HashMap();
           extentTable = new HashMap();
       }
   
  @@ -141,6 +139,35 @@
       }
   
       /**
  +     * Remove a pair of extent/classdescriptor from the extentTable.
  +     * @param classname the name of the extent itself
  +     */
  +    void removeExtent(String classname)
  +    {
  +        synchronized (extentTable)
  +        {
  +            // returns the super class for given extent class name
  +            ClassDescriptor cld = (ClassDescriptor) extentTable.remove(classname);
  +            if(cld != null && m_topLevelClassTable != null)
  +            {
  +                Class extClass = null;
  +                try
  +                {
  +                    extClass = ClassHelper.getClass(classname);
  +                }
  +                catch (ClassNotFoundException e)
  +                {
  +                    // Should not happen
  +                    throw new MetadataException("Can't instantiate class object for needed
extent remove", e);
  +                }
  +                // remove extent from super class descriptor
  +                cld.removeExtentClass(classname);
  +                m_topLevelClassTable.remove(extClass);
  +            }
  +        }
  +    }
  +
  +    /**
        * Returns the top level (extent) class to which the given class belongs.
        * This may be a (abstract) base-class, an interface or the given class
        * itself if given class is not defined as an extent in other class
  @@ -151,8 +178,12 @@
        */
       public Class getTopLevelClass(Class clazz) throws ClassNotPersistenceCapableException
       {
  +        if(m_topLevelClassTable == null)
  +        {
  +            m_topLevelClassTable = new HashMap();
  +        }
           // try to find an extent that contains clazz
  -        Class retval = (Class) m_extentClassTable.get(clazz);
  +        Class retval = (Class) m_topLevelClassTable.get(clazz);
           if (retval == null)
           {
               synchronized (extentTable)
  @@ -162,8 +193,6 @@
                   {
                       // fix by Mark Rowell
                       // Changed to call getExtentClass recursively
  -                    // old version:
  -                    // extentClass = cld.getClassOfObject();
                       retval = getTopLevelClass(cld.getClassOfObject());
                       // if such an extent could not be found just return clazz itself.
                       if (retval == null)
  @@ -177,7 +206,7 @@
                       getDescriptorFor(clazz);
                       retval = clazz;
                   }
  -                m_extentClassTable.put(clazz, retval);
  +                m_topLevelClassTable.put(clazz, retval);
               }
           }
           return retval;
  @@ -190,13 +219,17 @@
        */
       public FieldDescriptor[] getFieldDescriptorsForMultiMappedTable(ClassDescriptor targetCld)
       {
  -        FieldDescriptor[] retval = (FieldDescriptor[]) m_multiMappedTableMap.get(targetCld);
  +        if(m_multiMappedTableMap == null)
  +        {
  +            m_multiMappedTableMap = new HashMap();
  +        }
  +        FieldDescriptor[] retval = (FieldDescriptor[]) m_multiMappedTableMap.get(targetCld.getClassNameOfObject());
           if (retval == null)
           {
               synchronized (m_multiMappedTableMap)
               {
                   retval = getAllMappedColumns(getClassesMappedToSameTable(targetCld));
  -                m_multiMappedTableMap.put(targetCld, retval);
  +                m_multiMappedTableMap.put(targetCld.getClassNameOfObject(), retval);
               }
           }
           return retval;
  @@ -278,10 +311,10 @@
           {
               if(cld.isExtent())
               {
  -                Vector extents = cld.getExtentClasses();
  +                List extents = cld.getExtentClasses();
                   for (int i = 0; i < extents.size(); i++)
                   {
  -                    ClassDescriptor extCld = (ClassDescriptor) extents.elementAt(i);
  +                    ClassDescriptor extCld = (ClassDescriptor) extents.get(i);
                       result = findFirstConcreteClass(extCld);
                       if(result != null) break;
                   }
  @@ -414,14 +447,53 @@
       public void put(String classname, ClassDescriptor cld)
       {
           cld.setRepository(this); // BRJ
  -        descriptorTable.put(classname, cld);
  -        Vector extentClasses = cld.getExtentClasses();
  -        for (int i = 0; i < extentClasses.size(); ++i)
  +        synchronized (descriptorTable)
  +        {
  +            descriptorTable.put(classname, cld);
  +            List extentClasses = cld.getExtentClasses();
  +            for (int i = 0; i < extentClasses.size(); ++i)
  +            {
  +                addExtent(((Class) extentClasses.get(i)).getName(), cld);
  +            }
  +            changeDescriptorEvent();
  +        }
  +    }
  +
  +    public void remove(String className)
  +    {
  +        synchronized (descriptorTable)
           {
  -            addExtent(((Class) extentClasses.get(i)).getName(), cld);
  +            ClassDescriptor cld = (ClassDescriptor) descriptorTable.remove(className);
  +            if(cld != null)
  +            {
  +                // class itself could no longer be a extent
  +                Iterator it = descriptorTable.values().iterator();
  +                while (it.hasNext())
  +                {
  +                    ((ClassDescriptor) it.next()).removeExtentClass(className);
  +                }
  +                removeExtent(className);
  +                List extentClasses = cld.getExtentClasses();
  +                for (int i = 0; i < extentClasses.size(); ++i)
  +                {
  +                    removeExtent(((Class) extentClasses.get(i)).getName());
  +                }
  +                changeDescriptorEvent();
  +            }
           }
       }
   
  +    public void remove(Class clazz)
  +    {
  +        remove(clazz.getName());
  +    }
  +
  +    private void changeDescriptorEvent()
  +    {
  +        m_multiMappedTableMap = null;
  +        m_topLevelClassTable = null;
  +    }
  +
       /**
        * Returns an iterator over all managed {@link ClassDescriptor}.
        */
  @@ -529,10 +601,11 @@
        * class descriptors to improve performance on subsequent requests
        * for those classes.
        *
  +     * <br/>
  +     * author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
        * @param className name of class whose descriptor we need to find.
        * @return ClassDescriptor for <code>className</code> or <code>null</code>
        * if no ClassDescriptor could be located.
  -     * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
        */
       protected ClassDescriptor discoverDescriptor(String className)
       {
  @@ -560,5 +633,10 @@
                   descriptorTable.put(className, result);
            }
           return result;
  +    }
  +
  +    protected void finalize() throws Throwable
  +    {
  +        LoggerFactory.getDefaultLogger().info("# finalize DescriptorRepository instance
#");
       }
   }
  
  
  
  1.75.2.1  +126 -59   db-ojb/src/java/org/apache/ojb/broker/metadata/ClassDescriptor.java
  
  Index: ClassDescriptor.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/ClassDescriptor.java,v
  retrieving revision 1.75
  retrieving revision 1.75.2.1
  diff -u -r1.75 -r1.75.2.1
  --- ClassDescriptor.java	11 Dec 2003 00:36:41 -0000	1.75
  +++ ClassDescriptor.java	19 Dec 2003 17:38:13 -0000	1.75.2.1
  @@ -73,8 +73,11 @@
   import org.apache.commons.lang.builder.ToStringBuilder;
   import org.apache.commons.lang.builder.ToStringStyle;
   import org.apache.ojb.broker.PersistenceBrokerException;
  +import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
   import org.apache.ojb.broker.accesslayer.RowReader;
   import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
  +import org.apache.ojb.broker.accesslayer.StatementsForClassFactory;
  +import org.apache.ojb.broker.accesslayer.StatementsForClassIF;
   import org.apache.ojb.broker.core.ValueContainer;
   import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
   import org.apache.ojb.broker.util.ClassHelper;
  @@ -157,21 +160,22 @@
        */
       private transient boolean ojbConcreteFieldCheckDone = false;
       private transient FieldDescriptor ojbConcreteClassField;
  +    /**
  +     * We have to bound {@link org.apache.ojb.broker.accesslayer.StatementsForClassIF}
  +     * instance to this class, because metadata may change.
  +     */
  +    private transient StatementsForClassIF statementsForClass;
       //---------------------------------------------------------------
       // end transient fields
       //---------------------------------------------------------------
   
  +    private DescriptorRepository m_repository;
       /**
        * optional class.method to be invoked to create object instance.  Both
        * of these must be present for this function to be successful.
        */
       private Class factoryClass;
  -
       private String baseClass = null;
  -
  -    private Vector superPersistentFieldDescriptors = null;
  -
  -    private DescriptorRepository m_repository;
       /**
        * transaction isolation level specified for this class, used in the ODMG server
        */
  @@ -192,52 +196,12 @@
        * the table name used to store the scalar attributes of this class
        */
       private String m_TableName = null;
  -    /**
  -     * the FieldDescriptors for the primitive attributes
  -     */
  -    private FieldDescriptor[] m_FieldDescriptions = null;
  -    /**
  -     * the descriptors for collection attributes
  -     */
  -    private Vector m_CollectionDescriptors = new Vector();
  -    /**
  -     * the descriptor for 1-1 reference attributes
  -     */
  -    private Vector m_ObjectReferenceDescriptors = new Vector();
  -    /**
  -     * the vector of indices used in DDL generation.
  -     */
  -    private Vector indexes = new Vector();
  -    /**
  -     * the non-primary key FieldDescriptors
  -     */
  -    private FieldDescriptor[] m_nonPkFieldDescriptors = null;
  -    /**
  -     * the primary key FieldDescriptors
  -     */
  -    private FieldDescriptor[] m_PkFieldDescriptors = null;
  -    /**
  -     * the read/write FieldDescriptors BRJ
  -     */
  -    private FieldDescriptor[] m_RwFieldDescriptors = null;
  -    private FieldDescriptor[] m_RwNonPkFieldDescriptors = null;
  -    /**
  -     * the optimistic lockingFieldDescriptors BRJ
  -     */
  -    private FieldDescriptor[] m_lockingFieldDescriptors = null;
  +    private Vector superPersistentFieldDescriptors = null;
       /**
        * the RowReader for this class
        */
       private RowReader m_rowReader = null;
       /**
  -     * the list of classes in the extent of this class. can be empty
  -     */
  -    private Vector extentClasses = new Vector();
  -    /**
  -     * the list of class names in the extent of this class. can be empty
  -     */
  -    private Vector extentClassNames = new Vector();
  -    /**
        * the class that this class extends
        */
       private String superClass;
  @@ -249,7 +213,6 @@
        * does the described class represent an interface?
        */
       private boolean m_isInterface = false;
  -
       /**
        * the proxy class for the described class, may be null
        */
  @@ -262,30 +225,78 @@
        * if false do not accept implicit locks on this class
        */
       private boolean acceptLocks = true;
  -
       /**
        * if true instances of this class are always refreshed
        * even if they are already in the cache.
        * false by default.
        */
       private boolean alwaysRefresh = false;
  -
       private int m_ProxyPrefetchingLimit = 50;
  -
       /**
        * optional, ObjectCacheDescriptor for representing class
        */
       private ObjectCacheDescriptor objectCacheDescriptor;
  +    /**
  +     * JMM: Cache information about the interfaces need for dynamic proxy.
  +     */
  +    private Class[] m_dynamicProxyClassInterfaces;
  +    /**
  +     * the vector of indices used in DDL generation.
  +     */
  +    private Vector indexes = new Vector();
   
  +    //-----------------------------------------------------------------
  +    //-----------------------------------------------------------------
  +    // !!! the following arrays and maps have take care of metadata changes!!!
  +    //-----------------------------------------------------------------
  +    //-----------------------------------------------------------------
       private FieldDescriptor m_autoIncrementField = null;
  +    /**
  +     * the FieldDescriptors for the primitive attributes
  +     */
  +    private FieldDescriptor[] m_FieldDescriptions = null;
  +    /**
  +     * the descriptors for collection attributes
  +     */
  +    private Vector m_CollectionDescriptors = new Vector();
  +    /**
  +     * the descriptor for 1-1 reference attributes
  +     */
  +    private Vector m_ObjectReferenceDescriptors = new Vector();
  +    /**
  +     * the non-primary key FieldDescriptors
  +     */
  +    private FieldDescriptor[] m_nonPkFieldDescriptors = null;
  +    /**
  +     * the primary key FieldDescriptors
  +     */
  +    private FieldDescriptor[] m_PkFieldDescriptors = null;
  +    /**
  +     * the read/write FieldDescriptors BRJ
  +     */
  +    private FieldDescriptor[] m_RwFieldDescriptors = null;
  +    private FieldDescriptor[] m_RwNonPkFieldDescriptors = null;
  +    /**
  +     * the optimistic lockingFieldDescriptors BRJ
  +     */
  +    private FieldDescriptor[] m_lockingFieldDescriptors = null;
  +    /**
  +     * the list of classes in the extent of this class. can be empty
  +     */
  +    private Vector extentClasses = new Vector();
  +    /**
  +     * the list of class names in the extent of this class. can be empty
  +     */
  +    private Vector extentClassNames = new Vector();
       private Map m_fieldDescriptorNameMap = null;
       private Map m_collectionDescriptorNameMap = null;
       private Map m_objectReferenceDescriptorsNameMap = null;
   
  -    /**
  -     * JMM: Cache information about the interfaces need for dynamic proxy.
  -     */
  -    private Class[] m_dynamicProxyClassInterfaces;
  +    //-----------------------------------------------------------------
  +    //-----------------------------------------------------------------
  +    // END of cached metadata information
  +    //-----------------------------------------------------------------
  +    //-----------------------------------------------------------------
   
   
       //---------------------------------------------------------------
  @@ -446,6 +457,24 @@
           m_RwNonPkFieldDescriptors = null;
       }
   
  +    public boolean removeFieldDescriptor(FieldDescriptor fld)
  +    {
  +        boolean result = false;
  +        if(m_FieldDescriptions == null) return result;
  +
  +        List list = new ArrayList(Arrays.asList(m_FieldDescriptions));
  +        result = list.remove(fld);
  +        m_FieldDescriptions = (FieldDescriptor[]) list.toArray(new FieldDescriptor[list.size()]);
  +
  +        m_fieldDescriptorNameMap = null;
  +        m_PkFieldDescriptors = null;
  +        m_nonPkFieldDescriptors = null;
  +        m_lockingFieldDescriptors = null;
  +        m_RwFieldDescriptors = null;
  +        m_RwNonPkFieldDescriptors = null;
  +        return result;
  +    }
  +
       /**
        * Returns all defined {@link CollectionDescriptor} for
        * this class descriptor.
  @@ -466,6 +495,12 @@
           m_collectionDescriptorNameMap = null;
       }
   
  +    public void removeCollectionDescriptor(CollectionDescriptor cod)
  +    {
  +        m_CollectionDescriptors.remove(cod);
  +        m_collectionDescriptorNameMap = null;
  +    }
  +
       /**
        * Returns all defined {@link ObjectReferenceDescriptor}.
        */
  @@ -485,6 +520,12 @@
           m_objectReferenceDescriptorsNameMap = null;
       }
   
  +    public void removeObjectReferenceDescriptor(ObjectReferenceDescriptor ord)
  +    {
  +        m_ObjectReferenceDescriptors.remove(ord);
  +        m_objectReferenceDescriptorsNameMap = null;
  +    }
  +
       /**
        * Get an ObjectReferenceDescriptor by name	BRJ
        * @param name
  @@ -546,21 +587,37 @@
       /**
        * add an Extent class to the current descriptor
        * @param newExtendClass
  +     * @deprecated use {@link #addExtentClass(String newExtentClass)} instead
  +     */
  +    public void addExtentClassName(Class newExtendClass)
  +    {
  +        addExtentClass(newExtendClass);
  +    }
  +
  +    /**
  +     * add an Extent class to the current descriptor
  +     * @param newExtendClass
        */
       public void addExtentClass(Class newExtendClass)
       {
           extentClasses.add(newExtendClass);
  -        this.addExtentClassName(newExtendClass.getName());
  +        this.addExtentClass(newExtendClass.getName());
       }
   
       /**
        * add an Extent class to the current descriptor
        * @param newExtentClassName name of the class to add
        */
  -    public void addExtentClassName(String newExtentClassName)
  +    public void addExtentClass(String newExtentClassName)
       {
           extentClassNames.add(newExtentClassName);
  -        m_repository.addExtent(newExtentClassName, this);
  +        if(m_repository != null) m_repository.addExtent(newExtentClassName, this);
  +    }
  +
  +    public void removeExtentClass(String extentClassName)
  +    {
  +        extentClassNames.remove(extentClassName);
  +        if(m_repository != null) m_repository.removeExtent(extentClassName);
       }
   
       /**
  @@ -570,7 +627,7 @@
        */
       public synchronized Vector getExtentClasses()
       {
  -        if (extentClassNames.size() > extentClasses.size())
  +        if (extentClassNames.size() != extentClasses.size())
           {
               extentClasses.clear();
               for (Iterator iter = extentClassNames.iterator(); iter.hasNext();)
  @@ -2012,5 +2069,15 @@
               ojbConcreteFieldCheckDone = true;
           }
           return ojbConcreteClassField;
  +    }
  +
  +    public StatementsForClassIF getStatementsForClass(ConnectionManagerIF conMan)
  +    {
  +        if(statementsForClass == null)
  +        {
  +           statementsForClass = StatementsForClassFactory.getInstance().
  +                   getStatementsForClass(conMan.getConnectionDescriptor(), this);
  +        }
  +        return statementsForClass;
       }
   }
  
  
  
  No                   revision
  No                   revision
  1.60.2.1  +3 -1      db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
  
  Index: PersistenceBrokerImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java,v
  retrieving revision 1.60
  retrieving revision 1.60.2.1
  diff -u -r1.60 -r1.60.2.1
  --- PersistenceBrokerImpl.java	13 Dec 2003 18:58:11 -0000	1.60
  +++ PersistenceBrokerImpl.java	19 Dec 2003 17:38:13 -0000	1.60.2.1
  @@ -340,6 +340,8 @@
           }
           finally
           {
  +            // free current used DescriptorRepository reference
  +            descriptorRepository = null;
               this.setClosed(true);
           }
           return true;
  
  
  
  No                   revision
  No                   revision
  1.43.2.1  +11 -32    db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
  
  Index: StatementManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
  retrieving revision 1.43
  retrieving revision 1.43.2.1
  diff -u -r1.43 -r1.43.2.1
  --- StatementManager.java	9 Dec 2003 17:19:59 -0000	1.43
  +++ StatementManager.java	19 Dec 2003 17:38:13 -0000	1.43.2.1
  @@ -63,8 +63,6 @@
   import java.util.Collection;
   import java.util.Enumeration;
   import java.util.Iterator;
  -import java.util.Map;
  -import java.util.WeakHashMap;
   
   import org.apache.ojb.broker.Identity;
   import org.apache.ojb.broker.PersistenceBroker;
  @@ -101,8 +99,6 @@
   {
       private Logger m_log = LoggerFactory.getLogger(StatementManager.class);
   
  -    /** internal table of StatementForClass objects */
  -    private Map m_statementTable = new WeakHashMap();
       /** the associated broker */
       private final PersistenceBroker m_broker;
       private Platform m_platform;
  @@ -110,6 +106,10 @@
        * Used when OJB run in JBoss
        * TODO: Find a better solution to handle OJB within JBoss
        * --> the JCA implementation should solve this problem
  +     *
  +     * arminw:
  +     * Seems with JBoss 3.2.2 or higher the problem is gone, so we
  +     * can deprecate this attribute sooner or later
        */
       private boolean m_eagerRelease;
       private ConnectionManagerIF m_conMan;
  @@ -122,27 +122,6 @@
           m_platform = PlatformFactory.getPlatformFor(m_conMan.getConnectionDescriptor());
       }
   
  -    /**
  -     * return a StatementsForClass object for the given ClassDescriptor\
  -     * Note; not important to synchronize completely as a threading issue in this code
  -     * will only result in a little extra code being executed
  -     */
  -    protected StatementsForClassIF getStatementsForClass(ClassDescriptor cds) throws PersistenceBrokerException
  -    {
  -        StatementsForClassIF sfc = (StatementsForClassIF) m_statementTable.get(cds);
  -        if (sfc == null)
  -        {
  -            synchronized (m_statementTable)
  -            {
  -                // 07.17.2003 - RB: StatementsForClassImpl is now configurable
  -                //sfc = (StatementsForClassIF) new StatementsForClassImpl(m_conMan.getConnectionDescriptor(),
cds);
  -                sfc = StatementsForClassFactory.getInstance().getStatementsForClass(m_conMan.getConnectionDescriptor(),
cds);
  -                m_statementTable.put(cds, sfc);
  -            }
  -        }
  -        return sfc;
  -    }
  -
       public void closeResources(Statement stmt, ResultSet rs)
       {
           if (m_log.isDebugEnabled())
  @@ -640,7 +619,7 @@
       {
           try
           {
  -            return getStatementsForClass(cld).getDeleteStmt(m_conMan.getConnection());
  +            return cld.getStatementsForClass(m_conMan).getDeleteStmt(m_conMan.getConnection());
           }
           catch (SQLException e)
           {
  @@ -660,7 +639,7 @@
       {
           try
           {
  -            return getStatementsForClass(cds).getGenericStmt(m_conMan.getConnection(),
scrollable);
  +            return cds.getStatementsForClass(m_conMan).getGenericStmt(m_conMan.getConnection(),
scrollable);
           }
           catch (LookupException e)
           {
  @@ -675,7 +654,7 @@
       {
           try
           {
  -            return getStatementsForClass(cds).getInsertStmt(m_conMan.getConnection());
  +            return cds.getStatementsForClass(m_conMan).getInsertStmt(m_conMan.getConnection());
           }
           catch (SQLException e)
           {
  @@ -694,7 +673,7 @@
       {
           try
           {
  -            return getStatementsForClass(cds).getPreparedStmt(m_conMan.getConnection(),
sql, scrollable);
  +            return cds.getStatementsForClass(m_conMan).getPreparedStmt(m_conMan.getConnection(),
sql, scrollable);
           }
           catch (LookupException e)
           {
  @@ -709,7 +688,7 @@
       {
           try
           {
  -            return getStatementsForClass(cds).getSelectByPKStmt(m_conMan.getConnection());
  +            return cds.getStatementsForClass(m_conMan).getSelectByPKStmt(m_conMan.getConnection());
           }
           catch (SQLException e)
           {
  @@ -728,7 +707,7 @@
       {
           try
           {
  -            return getStatementsForClass(cds).getUpdateStmt(m_conMan.getConnection());
  +            return cds.getStatementsForClass(m_conMan).getUpdateStmt(m_conMan.getConnection());
           }
           catch (SQLException e)
           {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message