You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2003/06/15 14:00:04 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/util/sequence SequenceManagerHelper.java AbstractSequenceManager.java SequenceManagerNativeImpl.java

arminw      2003/06/15 05:00:03

  Modified:    src/test/org/apache/ojb/broker/sequence
                        SequenceManagerTest.java
               src/java/org/apache/ojb/broker/util/sequence
                        SequenceManagerHelper.java
                        AbstractSequenceManager.java
                        SequenceManagerNativeImpl.java
  Log:
  - add test for sequence manager
  'autoNaming' feature
  - fix bug in sequence name
  generation
  - do cleanup
  
  Revision  Changes    Path
  1.21      +128 -36   db-ojb/src/test/org/apache/ojb/broker/sequence/SequenceManagerTest.java
  
  Index: SequenceManagerTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/sequence/SequenceManagerTest.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- SequenceManagerTest.java	29 Apr 2003 15:43:27 -0000	1.20
  +++ SequenceManagerTest.java	15 Jun 2003 12:00:03 -0000	1.21
  @@ -1,18 +1,14 @@
   package org.apache.ojb.broker.sequence;
   
  -import java.util.ArrayList;
  -import java.util.Iterator;
  -import java.util.List;
  -import java.util.TreeSet;
  -import java.util.Collection;
  -import java.io.Serializable;
  -
   import junit.framework.TestCase;
  +import org.apache.commons.lang.SerializationUtils;
   import org.apache.ojb.broker.*;
  +import org.apache.ojb.broker.metadata.ClassDescriptor;
  +import org.apache.ojb.broker.metadata.DescriptorRepository;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  -import org.apache.ojb.broker.metadata.SequenceDescriptor;
  -import org.apache.ojb.broker.metadata.MetadataManager;
   import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
  +import org.apache.ojb.broker.metadata.MetadataManager;
  +import org.apache.ojb.broker.metadata.SequenceDescriptor;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.query.QueryByCriteria;
  @@ -24,7 +20,13 @@
   import org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl;
   import org.apache.ojb.broker.util.sequence.SequenceManagerSeqHiLoImpl;
   import org.apache.ojb.broker.util.sequence.SequenceManagerStoredProcedureImpl;
  -import org.apache.commons.lang.SerializationUtils;
  +
  +import java.io.Serializable;
  +import java.util.ArrayList;
  +import java.util.Collection;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.TreeSet;
   
   /**
    * Tests to verify SequenceManager implementations - All sequence
  @@ -88,8 +90,6 @@
           if (generatedKeys == null) generatedKeys = new ArrayList();
           if (generatedKeys.size() > 1)
               return;
  -
  -
           else
           {
   
  @@ -97,11 +97,11 @@
               SequenceManager sm = broker.serviceSequenceManager();
               int seqGrabSize = 0;
               // we need the SM grab size
  -            if(sm instanceof SequenceManagerSeqHiLoImpl || sm instanceof SequenceManagerHighLowImpl)
  +            if (sm instanceof SequenceManagerSeqHiLoImpl || sm instanceof SequenceManagerHighLowImpl)
               {
                   SequenceDescriptor sd = broker.serviceConnectionManager().getConnectionDescriptor().getSequenceDescriptor();
                   String strSize = sd.getAttribute(SequenceManagerHighLowImpl.PROPERTY_GRAB_SIZE);
  -                if(strSize != null)
  +                if (strSize != null)
                   {
                       seqGrabSize = new Integer(strSize).intValue();
                   }
  @@ -111,7 +111,7 @@
               // the grab size have to be a factor of the loops number
               // to pass the 'testForLostKeys' test because we
               if (loops < seqGrabSize) loops = seqGrabSize;
  -            if(seqGrabSize != 0) loops = (loops / seqGrabSize) * seqGrabSize;
  +            if (seqGrabSize != 0) loops = (loops / seqGrabSize) * seqGrabSize;
   
               brokers = new PersistenceBroker[instances];
               for (int i = 0; i < instances; i++)
  @@ -187,6 +187,99 @@
           broker.close();
       }
   
  +    public void testAutoNaming() throws Exception
  +    {
  +        String jcdAlias = "testAutoNaming";
  +        PBKey tempKey = new PBKey(jcdAlias, TestHelper.DEF_KEY.getUser(), TestHelper.DEF_KEY.getPassword());
  +        MetadataManager mm = MetadataManager.getInstance();
  +        PersistenceBroker broker = null;
  +        try
  +        {
  +            JdbcConnectionDescriptor jcd = mm.connectionRepository().getDescriptor(TestHelper.DEF_KEY);
  +            jcd = (JdbcConnectionDescriptor) SerializationUtils.clone(jcd);
  +            // modify jcd copy
  +            jcd.setJcdAlias(jcdAlias);
  +            SequenceDescriptor sd = jcd.getSequenceDescriptor();
  +            assertNotNull("Can not find sequence-descriptor - check test", sd);
  +            // don't use autoNaming
  +            sd.addAttribute("autoNaming", "false");
  +            // add new connection descriptor to global base
  +            mm.connectionRepository().addDescriptor(jcd);
  +
  +            // allow per thread changes of persistent object data
  +            mm.setEnablePerThreadChanges(true);
  +            DescriptorRepository dr = mm.copyOfGlobalRepository();
  +            ClassDescriptor cld = dr.getDescriptorFor(SMObjectTwo.class);
  +            FieldDescriptor field = cld.getAutoIncrementField();
  +            // set sequence name for persistent object to null
  +            field.setSequenceName(null);
  +            mm.setDescriptor(dr);
  +
  +            broker = PersistenceBrokerFactory.createPersistenceBroker(tempKey);
  +            try
  +            {
  +                /*
  +                persistent object descriptor doesn't has a sequence name
  +                and autoNaming is false --> expect an exception
  +                */
  +                SMObjectTwo obj = new SMObjectTwo("testAutoNaming");
  +                broker.beginTransaction();
  +                broker.store(obj);
  +                broker.commitTransaction();
  +                fail("This test should cause an exception");
  +            }
  +            catch (PersistenceBrokerException e)
  +            {
  +                assertTrue(true);
  +                broker.abortTransaction();
  +            }
  +
  +            try
  +            {
  +                // now we set a sequence name for autoincrement field
  +                // should pass
  +                field.setSequenceName("SEQ_testAutoNaming");
  +                SMObjectTwo obj = new SMObjectTwo("testAutoNaming");
  +                broker.beginTransaction();
  +                broker.store(obj);
  +                broker.commitTransaction();
  +                broker.close();
  +            }
  +            catch (PersistenceBrokerException e)
  +            {
  +                fail("Sequence key generation failed");
  +            }
  +
  +            try
  +            {
  +                /*
  +                remove sequence name of autoincrement field
  +                and enable automatic sequence name generation
  +                */
  +                field.setSequenceName(null);
  +                sd.addAttribute("autoNaming", "true");
  +                PersistenceBrokerFactory.releaseAllInstances();
  +                broker = PersistenceBrokerFactory.createPersistenceBroker(tempKey);
  +                SMObjectTwo obj = new SMObjectTwo("testAutoNaming");
  +                broker.beginTransaction();
  +                broker.store(obj);
  +                broker.commitTransaction();
  +            }
  +            catch (PersistenceBrokerException e)
  +            {
  +                e.printStackTrace();
  +                fail("Sequence key generation failed");
  +            }
  +
  +        }
  +        finally
  +        {
  +            // cleanup
  +            if (broker != null) broker.close();
  +            mm.setEnablePerThreadChanges(false);
  +        }
  +    }
  +
       /**
        * This test only works, when using
        * {@link org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl}
  @@ -196,21 +289,21 @@
       {
           PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker();
           SequenceManager sm = SequenceManagerFactory.getSequenceManager(broker);
  -        if(!(sm instanceof SequenceManagerNextValImpl))
  +        if (!(sm instanceof SequenceManagerNextValImpl))
           {
               System.out.println("This test only works for SeqMan implementations using "
  -                    +SequenceManagerNextValImpl.class+" Skip test case.");
  +                    + SequenceManagerNextValImpl.class + " Skip test case.");
               broker.close();
               return;
           }
           int count = 0;
           FieldDescriptor idFld = broker.getClassDescriptor(
  -                    SMDatabaseSequence.class).getAutoIncrementField();
  +                SMDatabaseSequence.class).getAutoIncrementField();
           for (int i = 0; i < 10; i++)
           {
  -        	Integer val = (Integer) sm.getUniqueValue(idFld);
  +            Integer val = (Integer) sm.getUniqueValue(idFld);
               count += val.intValue();
  -            System.err.println("count "+count);
  +            System.err.println("count " + count);
           }
           assertFalse("No keys generated", count == 0);
           broker.close();
  @@ -416,7 +509,7 @@
           int result;
           for (int i = 0; i < number; i++)
           {
  -        	Integer val = (Integer) sm.getUniqueValue(field);
  +            Integer val = (Integer) sm.getUniqueValue(field);
               result = val.intValue();
               resultList.add(new Integer(result));
           }
  @@ -436,8 +529,8 @@
           int id2 = val.intValue();
           assertTrue(id1 != id2);
           assertTrue(id2 > id1);
  -        assertTrue("If the sequence manger implementation does not support continuous key generation"+
  -        " per PB instance, you could ignore this failure", (id2 - id1) == 1);
  +        assertTrue("If the sequence manger implementation does not support continuous key generation" +
  +                " per PB instance, you could ignore this failure", (id2 - id1) == 1);
       }
   
       /**
  @@ -463,8 +556,8 @@
           TreeSet set = new TreeSet((List) generatedKeys.clone());
           if (set.isEmpty()) fail("No generated keys found");
           int result = ((Integer) set.last()).intValue() - ((Integer) set.first()).intValue() + 1;
  -        assertEquals("Sequence manager lost sequence numbers, this could be a failure or could be"+
  -                " the volitional behaviour of the sequence manager"+
  +        assertEquals("Sequence manager lost sequence numbers, this could be a failure or could be" +
  +                " the volitional behaviour of the sequence manager" +
                   " - retry test case, check test case, check sequence manager implementation.", keyCount, result);
       }
   
  @@ -522,7 +615,7 @@
       public void YYYtestSequenceManagerStoredProcedureImpl() throws Exception
       {
           JdbcConnectionDescriptor jcd = MetadataManager.getInstance().connectionRepository().
  -                                        getDescriptor(PersistenceBrokerFactory.getDefaultKey());
  +                getDescriptor(PersistenceBrokerFactory.getDefaultKey());
           SequenceDescriptor old_sd = (SequenceDescriptor) SerializationUtils.clone(jcd.getSequenceDescriptor());
           PersistenceBroker broker;
           try
  @@ -531,9 +624,9 @@
               PersistenceBrokerFactory.releaseAllInstances();
               broker = PersistenceBrokerFactory.defaultPersistenceBroker();
               SequenceManager sm = broker.serviceSequenceManager();
  -            if(! (sm instanceof SequenceManagerStoredProcedureImpl))
  +            if (!(sm instanceof SequenceManagerStoredProcedureImpl))
               {
  -                fail("testSM_StoredProcedure: Expected sequence manager implemenation was "+
  +                fail("testSM_StoredProcedure: Expected sequence manager implemenation was " +
                           SequenceManagerStoredProcedureImpl.class.getName());
                   return;
               }
  @@ -550,7 +643,7 @@
           }
           finally
           {
  -            if(old_sd != null)
  +            if (old_sd != null)
               {
   
                   PersistenceBrokerFactory.releaseAllInstances();
  @@ -612,7 +705,7 @@
   
       protected static synchronized void addResultList(List resultList)
       {
  -        System.out.println(" add "+ resultList.size() +"generated Keys");
  +        System.out.println(" add " + resultList.size() + "generated Keys");
           if (resultList == null) return;
           generatedKeys.addAll(resultList);
       }
  @@ -623,7 +716,6 @@
       }
   
   
  -
       public void testObjectsFromAbstractBaseClass1() throws Exception
       {
           PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  @@ -653,15 +745,15 @@
           }
           finally
           {
  -            if(broker != null) broker.close();
  +            if (broker != null) broker.close();
           }
       }
   
       public void testObjectsFromAbstractBaseClass2() throws Exception
       {
           long stamp = System.currentTimeMillis();
  -        String objectName_One = "testObjectsFromAbstractBaseClass2_objOne_"+stamp;
  -        String objectName_Two = "testObjectsFromAbstractBaseClass2_objTwo_"+stamp;
  +        String objectName_One = "testObjectsFromAbstractBaseClass2_objOne_" + stamp;
  +        String objectName_Two = "testObjectsFromAbstractBaseClass2_objTwo_" + stamp;
   
           PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker();
   
  @@ -708,7 +800,7 @@
           }
           finally
           {
  -            if(broker != null) broker.close();
  +            if (broker != null) broker.close();
           }
       }
   
  
  
  
  1.13      +69 -12    db-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHelper.java
  
  Index: SequenceManagerHelper.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHelper.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- SequenceManagerHelper.java	12 May 2003 09:18:06 -0000	1.12
  +++ SequenceManagerHelper.java	15 Jun 2003 12:00:03 -0000	1.13
  @@ -11,6 +11,8 @@
   import java.sql.ResultSet;
   import java.sql.SQLException;
   import java.sql.Statement;
  +import java.util.Collection;
  +import java.util.Iterator;
   import java.util.Vector;
   
   /**
  @@ -24,6 +26,7 @@
       private static Logger log = LoggerFactory.getLogger(SequenceManagerHelper.class);
   
       private static final String SEQ_PREFIX = "SEQ_";
  +    private static final String SEQ_UNASSIGNED = "UNASSIGNED";
       private static final String SM_SELECT_MAX = "SELECT MAX(";
       private static final String SM_FROM = ") FROM ";
   
  @@ -33,15 +36,21 @@
   
       /**
        * Returns a unique sequence name (unique across all extents).
  -     * <br>
  +     * <br/>
        * If we found a non null value for the 'sequence-name' attribute in
        * the field descriptor, we use the 'sequence-name' value as sequence name.
  -     * <br>
  +     * <br/>
        * Else if the top-level class of the target class has extents,
        * we take the first extent class table name of the extents as
        * sequence name.
  -     * <br>
  +     * <br/>
        * Else we take the table name of the target class.
  +     * <p>
  +     * If the method argument 'autoNaming' is true, the generated
  +     * sequence name will be set in the given field descriptor
  +     * using {@link org.apache.ojb.broker.metadata.FieldDescriptor#setSequenceName}
  +     * to speed up sequence name lookup in future calls.
  +     * </p>
        * @param brokerForClass current used PB instance
        * @param field target field
        * @param autoNaming if 'false' no auto sequence name was build and
  @@ -49,7 +58,7 @@
        */
       public static String buildSequenceName(PersistenceBroker brokerForClass,
                                              FieldDescriptor field, boolean autoNaming)
  -                                            throws SequenceManagerException
  +            throws SequenceManagerException
       {
           String seqName = field.getSequenceName();
           /*
  @@ -60,15 +69,18 @@
           {
               return seqName;
           }
  -        else if(!autoNaming)
  +        else if (!autoNaming)
           {
               /*
               arminw:
  -            we don't found a sequence name and we should not automatic build one,
  +            we don't find a sequence name and we should not automatic build one,
               thus we throw an exception
               */
  -            throw new SequenceManagerException("Could not find sequence-name for "+
  -                            field+" property 'autoNaming' in sequence-manager element in repository was "+autoNaming);
  +            throw new SequenceManagerException("Could not find sequence-name for field '" +
  +                    field + "' of class '" + field.getClassDescriptor().getClassNameOfObject() +
  +                    "', property 'autoNaming' in sequence-manager element in repository was '" +
  +                    autoNaming + "'. Set autoNaming true in sequence-descriptor or define a " +
  +                    " sequence-name in field-descriptor.");
           }
   
           ClassDescriptor cldTargetClass = field.getClassDescriptor();
  @@ -99,15 +111,60 @@
               sequence manager docs
               TODO: find better solution
               */
  -            seqName = brokerForClass.getClassDescriptor(((Class) cldTopLevel.getExtentClasses().
  -                    get(0))).getFullTableName();
  +//            seqName = brokerForClass.getClassDescriptor(((Class) cldTopLevel.getExtentClasses().
  +//                    get(0))).getFullTableName();
  +            seqName = firstFoundTableName(brokerForClass, cldTopLevel);
           }
           else
           {
               seqName = cldTargetClass.getFullTableName();
           }
   //        log.info("* targetClass: "+targetClass +", toplevel: "+topLevel+ " seqName: "+seqName);
  -        return SEQ_PREFIX + seqName;
  +        if (seqName == null)
  +        {
  +            seqName = SEQ_UNASSIGNED;
  +            log.warn("Too complex structure, can not assign automatic sequence name for field '" +
  +                    field.getAttributeName() + "' in class '" +
  +                    field.getClassDescriptor().getClassNameOfObject() +
  +                    "'. Use a default sequence name instead: " + (SEQ_PREFIX + seqName));
  +        }
  +//        System.out.println("* targetClass: " + cldTargetClass.getClassNameOfObject() + ", toplevel: " + topLevel + " seqName: " + seqName);
  +        seqName = SEQ_PREFIX + seqName;
  +        if (autoNaming)
  +        {
  +            if (log.isDebugEnabled())
  +                log.debug("Set automatic generated sequence-name for field '" +
  +                        field.getAttributeName() + "' in class '" +
  +                        field.getClassDescriptor().getClassNameOfObject() +
  +                        "'.");
  +            field.setSequenceName(seqName);
  +        }
  +        return seqName;
  +    }
  +
  +    /**
  +     * try to find the first none null table name for the given class-descriptor.
  +     * If cld has extent classes, all of these cld's searched for the first none null
  +     * table name.
  +     */
  +    private static String firstFoundTableName(PersistenceBroker brokerForClass, ClassDescriptor cld)
  +    {
  +        String name = null;
  +        if (!cld.isInterface() && cld.getFullTableName() != null)
  +        {
  +            return cld.getFullTableName();
  +        }
  +        if (cld.isExtent())
  +        {
  +            Collection extentClasses = cld.getExtentClasses();
  +            for (Iterator iterator = extentClasses.iterator(); iterator.hasNext();)
  +            {
  +                name = firstFoundTableName(brokerForClass, brokerForClass.getClassDescriptor((Class) iterator.next()));
  +                // System.out.println("## " + cld.getClassNameOfObject()+" - name: "+name);
  +                if (name != null) break;
  +            }
  +        }
  +        return name;
       }
   
       /**
  
  
  
  1.10      +13 -14    db-ojb/src/java/org/apache/ojb/broker/util/sequence/AbstractSequenceManager.java
  
  Index: AbstractSequenceManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/sequence/AbstractSequenceManager.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- AbstractSequenceManager.java	12 May 2003 08:57:37 -0000	1.9
  +++ AbstractSequenceManager.java	15 Jun 2003 12:00:03 -0000	1.10
  @@ -36,7 +36,7 @@
       private PersistenceBroker brokerForClass;
       private Platform platform;
       private Properties configurationProperties;
  -    private boolean autoNaming;
  +    private Boolean autoNaming;
   
       /**
        * Constructor used by
  @@ -48,19 +48,14 @@
       public AbstractSequenceManager(PersistenceBroker broker)
       {
           this.brokerForClass = broker;
  -        this.platform = broker.serviceConnectionManager().getSupportedPlatform();
  -        SequenceDescriptor sd = broker.serviceConnectionManager().
  +        this.configurationProperties = new Properties();
  +        this.platform = brokerForClass.serviceConnectionManager().getSupportedPlatform();
  +        SequenceDescriptor sd = brokerForClass.serviceConnectionManager().
                   getConnectionDescriptor().getSequenceDescriptor();
  -        if (sd == null)
  +        if (sd != null)
           {
  -            this.configurationProperties = new Properties();
  +            this.configurationProperties.putAll(sd.getConfigurationProperties());
           }
  -        else
  -        {
  -            this.configurationProperties = sd.getConfigurationProperties();
  -        }
  -        autoNaming =
  -                new Boolean(getConfigurationProperty(PROPERTY_AUTO_NAMING, "true")).booleanValue();
       }
   
       /**
  @@ -87,7 +82,7 @@
   
       public void setConfigurationProperties(Properties prop)
       {
  -        this.configurationProperties = prop != null ?  prop : new Properties();
  +        this.configurationProperties.putAll(prop);
       }
   
       public String getConfigurationProperty(String key, String defaultValue)
  @@ -103,7 +98,11 @@
   
       public boolean useAutoNaming()
       {
  -        return autoNaming;
  +        if (autoNaming == null)
  +        {
  +            autoNaming = new Boolean(getConfigurationProperty(PROPERTY_AUTO_NAMING, "true"));
  +        }
  +        return autoNaming.booleanValue();
       }
   
   
  
  
  
  1.5       +4 -6      db-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerNativeImpl.java
  
  Index: SequenceManagerNativeImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerNativeImpl.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SequenceManagerNativeImpl.java	5 Jun 2003 18:30:46 -0000	1.4
  +++ SequenceManagerNativeImpl.java	15 Jun 2003 12:00:03 -0000	1.5
  @@ -104,7 +104,7 @@
    * <p>
    * <b>Limitations:</b>
    * <ul>
  - * <li>native key generation is not extent aware,
  + * <li>native key generation is not 'extent aware',
    * when extent classes span several tables! Please
    * see more in shipped docs 'extents and polymorphism'.
    * </li>
  @@ -122,17 +122,16 @@
       private Log log = LogFactory.getLog(SequenceManagerNativeImpl.class);
       /*
        TODO:
  -     Find a better solution for this problem
  +     1. Find a better solution for this problem
        We need this dummy field to return a negative long value
        on getUniqueLong(...) call. If we return always the same
        value, the resulting Identity object was found on cache.
        arminw:
        seems to work when always -1 was returned
   
  -     Second problem is that generated oid (by Identity column)
  +     2. Problem is that generated oid (by Identity column)
        must not begin with 0.
        */
  -//    private static long idDummy;
   
       public SequenceManagerNativeImpl(PersistenceBroker broker)
       {
  @@ -365,7 +364,6 @@
        */
       protected long getUniqueLong(FieldDescriptor field) throws SequenceManagerException
       {
  -        // return --idDummy;
           return -1;
       }
   }