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/01/09 18:09:31 UTC

cvs commit: jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence SequenceManagerSeqHiLoImpl.java AbstractSequenceManager.java SequenceGenerator.java SequenceManagerFactory.java SequenceManagerHelper.java SequenceManagerHighLowImpl.java SequenceManagerInMemoryImpl.java SequenceManagerNextValImpl.java

arminw      2003/01/09 09:09:31

  Modified:    src/java/org/apache/ojb/broker/util/sequence
                        AbstractSequenceManager.java SequenceGenerator.java
                        SequenceManagerFactory.java
                        SequenceManagerHelper.java
                        SequenceManagerHighLowImpl.java
                        SequenceManagerInMemoryImpl.java
                        SequenceManagerNextValImpl.java
  Added:       src/java/org/apache/ojb/broker/util/sequence
                        SequenceManagerSeqHiLoImpl.java
  Log:
  - move the whole sequence-manager
  properties stuff from the OJB.properties to
  the repository
  - move the 'useAutoCommit' and
  'ignoreAutocommitExceptions' properties from OJB.properties
  to jdbc-connection-descriptor
  
  - remove the 'maxConnectionsInPool'
  property from OJB.properties
  
  - rename DescriptorRepository#getExtentClass
  to #getTopLevelClass, deprecate PB#getExtentClass
  and add PB#getTopLevelClass
  
  Revision  Changes    Path
  1.4       +41 -48    jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/AbstractSequenceManager.java
  
  Index: AbstractSequenceManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/AbstractSequenceManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractSequenceManager.java	22 Nov 2002 00:13:59 -0000	1.3
  +++ AbstractSequenceManager.java	9 Jan 2003 17:09:31 -0000	1.4
  @@ -1,99 +1,92 @@
   package org.apache.ojb.broker.util.sequence;
   
  -import org.apache.ojb.broker.PBKey;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.accesslayer.JdbcAccess;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  -import org.apache.ojb.broker.util.configuration.Configurable;
  -import org.apache.ojb.broker.util.configuration.Configuration;
  -import org.apache.ojb.broker.util.configuration.ConfigurationException;
  -import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
  +import org.apache.ojb.broker.metadata.SequenceDescriptor;
  +import org.apache.ojb.broker.platforms.Platform;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   
  +import java.util.Properties;
  +
   /**
    * A base class for sequence manager implementations.
  + * <br/>
    * All sequence manager implementations need a constructor
  - * with a PersistenceBroker argument.
  + * with a PersistenceBroker argument used by the
  + * {@link org.apache.ojb.broker.util.sequence.SequenceManagerFactory}.
    *
    * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
    * @version $Id$
    */
  -public abstract class AbstractSequenceManager implements SequenceManager, Configurable
  +public abstract class AbstractSequenceManager implements SequenceManager
   {
       private Logger log = LoggerFactory.getLogger(AbstractSequenceManager.class);
   
  -    private int grabSize;
  -    private boolean globalSequenceIdentities;
       private PersistenceBroker brokerForClass;
  -    /**
  -     * if not null, this should induce the
  -     * sequence manager implementation to use
  -     * this PBKey for access to the sequence tables
  -     */
  -    private PBKey keyToSeparateSeqTable = null;
  +    private Platform platform;
  +    private Properties configurationProperties;
   
       /**
  -     * Constructor used by the {@link SequenceManagerFactory} object
  +     * Constructor used by
  +     * {@link org.apache.ojb.broker.util.sequence.SequenceManagerFactory}
        *
  -     * @param broker  This PB instance is required to perform the
  +     * @param broker  PB instance to perform the
        * id generation.
        */
       public AbstractSequenceManager(PersistenceBroker broker)
       {
           this.brokerForClass = broker;
  -        OjbConfigurator.getInstance().configure(this);
  -    }
  -
  -    public void configure(Configuration pConfig) throws ConfigurationException
  -    {
  -        SequenceConfiguration conf = (SequenceConfiguration) pConfig;
  -        grabSize = conf.getSequenceManagerGrabSize();
  -        keyToSeparateSeqTable = conf.getSeparatePBKey();
  -        globalSequenceIdentities = conf.getSequenceManagerGlobalId();
  +        this.platform = broker.serviceConnectionManager().getSupportedPlatform();
  +        SequenceDescriptor sd = broker.serviceConnectionManager().
  +                getConnectionDescriptor().getSequenceDescriptor();
  +        if (sd == null)
  +        {
  +            this.configurationProperties = new Properties();
  +        }
  +        else
  +        {
  +            this.configurationProperties = sd.getConfigurationProperties();
  +        }
       }
   
  -
  -    public int getGrabSize()
  +    public Platform getPlatform()
       {
  -        return grabSize;
  +        return platform;
       }
   
  -    public void setGrabSize(int defaultGrabSize)
  +    public PersistenceBroker getBrokerForClass()
       {
  -        this.grabSize = defaultGrabSize;
  +        return brokerForClass;
       }
   
  -    public boolean isGlobalSequenceIdentities()
  +    public Properties getConfigurationProperties()
       {
  -        return globalSequenceIdentities;
  +        return this.configurationProperties;
       }
   
  -    public void setGlobalSequenceIdentities(boolean globalValidIdentities)
  +    public void setConfigurationProperties(Properties prop)
       {
  -        this.globalSequenceIdentities = globalValidIdentities;
  +        this.configurationProperties = prop != null ?  prop : new Properties();
       }
   
  -    public PersistenceBroker getBrokerForClass()
  +    public String getConfigurationProperty(String key, String defaultValue)
       {
  -        return brokerForClass;
  +        String result = this.configurationProperties.getProperty(key);
  +        return result != null ? result : defaultValue;
       }
   
  -    public void setBrokerForClass(PersistenceBroker brokerForClass)
  +    public void setConfigurationProperty(String key, String value)
       {
  -        this.brokerForClass = brokerForClass;
  +        this.configurationProperties.setProperty(key, value);
       }
   
  -    public PBKey getKeyToSeparateSeqTable()
  -    {
  -        return keyToSeparateSeqTable;
  -    }
   
  -    public void setKeyToSeparateSeqTable(PBKey keyToSeparateSeqTable)
  -    {
  -        this.keyToSeparateSeqTable = keyToSeparateSeqTable;
  -    }
  +    //****************************************************************
  +    // method implementations of SequenceManager interface
  +    //****************************************************************
   
       /**
        * returns a unique String for class clazz and field fieldName.
  
  
  
  1.14      +95 -64    jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceGenerator.java
  
  Index: SequenceGenerator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceGenerator.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- SequenceGenerator.java	24 Dec 2002 13:24:28 -0000	1.13
  +++ SequenceGenerator.java	9 Jan 2003 17:09:31 -0000	1.14
  @@ -1,7 +1,5 @@
   package org.apache.ojb.broker.util.sequence;
   
  -import org.apache.ojb.broker.PBFactoryException;
  -import org.apache.ojb.broker.PBKey;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.PersistenceBrokerFactory;
  @@ -12,11 +10,9 @@
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   
   /**
  - * Sequence generator used within sequence manager
  - * implementations using H/L sequence generation.
  - * @see SequenceManagerHiLoImpl
  - * @see SequenceManagerHiLoContinuousImpl
  + * Helper class used for {@link HighLowSequence} management.
    *
  + * @see SequenceManagerHighLowImpl
    * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
    * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
    * @version $Id$
  @@ -26,37 +22,29 @@
       private static Logger log = LoggerFactory.getLogger(SequenceGenerator.class);
   
       /**
  -     * Return the next sequence of keys.
  -     * @param brokerForClass PB instance responsible for the given class
  -     * @param clazz Class of the object, we need the next sequence
  +     * Return the next sequence of keys (threadsafe).
  +     *
  +     * @param brokerForSequence PB instance used for sequence operation
        * @param targetSequence Sequence who was exhausted
  -     * @param keyForSequenceOperation Optional. {@link org.apache.ojb.broker.PBKey}
  -     * used to lookup a separate PB to perform key generation (see {@link SequenceGenerator})
        */
  -    public synchronized static HighLowSequence getNextSequence(PersistenceBroker brokerForClass,
  -                                                               HighLowSequence targetSequence,
  -                                                               PBKey keyToSeparateSeqTable)
  +    public synchronized static HighLowSequence getNextSequence(PersistenceBroker brokerForSequence,
  +                                                               HighLowSequence targetSequence)
       {
  -        PersistenceBroker broker_seq = null;
           HighLowSequence newSequence = null;
  -
  +        PersistenceBroker broker = null;
           try
           {
               if (log.isDebugEnabled()) log.debug("prepare next sequence for sequence " + targetSequence);
  -            // lookup for sequence in db
  -            // here we use a default PB instance or the PB specified
  -            // via 'keyToSeparateSeqTable' to lookup OJB internal
  -            // sequence table
  -            broker_seq = getBrokerForSequenceOperations(keyToSeparateSeqTable);
   
               Criteria c = new Criteria();
               c.addLike("tableName", targetSequence.getTableName());
               c.addLike("fieldName", targetSequence.getFieldName());
               Query q = new QueryByCriteria(targetSequence.getClass(), c);
  -            broker_seq.beginTransaction();
  -            newSequence = (HighLowSequence) broker_seq.getObjectByQuery(q);
  -            broker_seq.commitTransaction();
   
  +            broker = PersistenceBrokerFactory.createPersistenceBroker(brokerForSequence.getPBKey());
  +            broker.beginTransaction();
  +
  +            newSequence = (HighLowSequence) broker.getObjectByQuery(q);
   
               //not in db --> we store the targetSequence
               if (newSequence == null)
  @@ -79,10 +67,11 @@
               newSequence = newSequence.getCopy();
               //grab the next key scope
               newSequence.grabNextKeySet();
  +
               //store the sequence to db
  -            broker_seq.beginTransaction();
  -            broker_seq.store(newSequence);
  -            broker_seq.commitTransaction();
  +            broker.store(newSequence);
  +
  +            broker.commitTransaction();
   
               if (log.isDebugEnabled()) log.debug("new sequence was " + newSequence);
           }
  @@ -93,44 +82,86 @@
           }
           finally
           {
  -            if (broker_seq != null)
  -            {
  -                broker_seq.close();
  -            }
  +            if (broker != null) broker.close();
           }
           return newSequence;
       }
   
  -    /**
  -     * @see #getNextSequence(PersistenceBroker, HighLowSequence,PBKey)
  -     */
  -    public synchronized static HighLowSequence getNextSequence(PersistenceBroker brokerForClass,
  -                                                               HighLowSequence targetSequence)
  -    {
  -        return getNextSequence(brokerForClass, targetSequence, null);
  -    }
  -
  -    /**
  -     * To obtain a new {@link HighLowSequence} we need access to the OJB internal
  -     * tables, thus we need a PB instance matching these tables.
  -     */
  -    private static PersistenceBroker getBrokerForSequenceOperations(PBKey key)
  -    {
  -        try
  -        {
  -            if (key == null)
  -            {
  -                return PersistenceBrokerFactory.defaultPersistenceBroker();
  -            }
  -            else
  -            {
  -                return PersistenceBrokerFactory.createPersistenceBroker(key);
  -            }
  -        }
  -        catch (PBFactoryException e)
  -        {
  -            log.error("Can not obtain a PB instance", e);
  -            throw new PersistenceBrokerException(e);
  -        }
  -    }
  +/*
  +TODO use this method implementation when we implemented a 'TransactionListener' or callback
  +concept for tx.
  +Problem: If a a new HighLowSequence was obtained during a tx and the tx fails when
  +commit was called, the HighLowSequence entry was rollback too, but the sequence manager
  +implementation meanwhile use the new HighLowSequence and must be notify to discard this sequence.
  +
  +Till this was not realized we use a separate PB instance to store new HighLowSequences.
  +In managed environments we run into the same problem, because normally we use the same
  +connection within serveral PB instances.
  +*/
  +
  +//
  +//    /**
  +//     * Return the next sequence of keys (threadsafe).
  +//     *
  +//     * @param brokerForSequence PB instance used for sequence operation
  +//     * @param targetSequence Sequence who was exhausted
  +//     */
  +//    public synchronized static HighLowSequence getNextSequence(PersistenceBroker brokerForSequence,
  +//                                                               HighLowSequence targetSequence)
  +//    {
  +//        HighLowSequence newSequence = null;
  +//        boolean needsCommit = false;
  +//        try
  +//        {
  +//            if (log.isDebugEnabled()) log.debug("prepare next sequence for sequence " + targetSequence);
  +//
  +//            Criteria c = new Criteria();
  +//            c.addLike("tableName", targetSequence.getTableName());
  +//            c.addLike("fieldName", targetSequence.getFieldName());
  +//            Query q = new QueryByCriteria(targetSequence.getClass(), c);
  +//
  +//            if(!brokerForSequence.isInTransaction())
  +//            {
  +//                brokerForSequence.beginTransaction();
  +//                needsCommit = true;
  +//            }
  +//            newSequence = (HighLowSequence) brokerForSequence.getObjectByQuery(q);
  +//
  +//            //not in db --> we store the targetSequence
  +//            if (newSequence == null)
  +//            {
  +//                if (log.isDebugEnabled())
  +//                {
  +//                    log.debug("sequence not found in db, store the given sequence as new: " + targetSequence);
  +//                }
  +//                newSequence = targetSequence;
  +//            }
  +//            // if given maxKey greater that the stored in DB
  +//            // we use the greater one
  +//            if (targetSequence.getMaxKey() > newSequence.getMaxKey())
  +//            {
  +//                newSequence.setMaxKey(targetSequence.getMaxKey());
  +//            }
  +//            //set current grab size
  +//            newSequence.setGrabSize(targetSequence.getGrabSize());
  +//            //use copy to avoid sync problems!!
  +//            newSequence = newSequence.getCopy();
  +//            //grab the next key scope
  +//            newSequence.grabNextKeySet();
  +//
  +//            //store the sequence to db
  +//            brokerForSequence.store(newSequence);
  +//            if(needsCommit)
  +//            {
  +//                brokerForSequence.commitTransaction();
  +//            }
  +//            if (log.isDebugEnabled()) log.debug("new sequence was " + newSequence);
  +//        }
  +//        catch (Exception e)
  +//        {
  +//            log.error("Can not get next " + HighLowSequence.class.getName() + " for next scope of keys", e);
  +//            throw new PersistenceBrokerException(e);
  +//        }
  +//        return newSequence;
  +//    }
   }
  
  
  
  1.4       +22 -20    jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerFactory.java
  
  Index: SequenceManagerFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerFactory.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SequenceManagerFactory.java	9 Aug 2002 10:49:20 -0000	1.3
  +++ SequenceManagerFactory.java	9 Jan 2003 17:09:31 -0000	1.4
  @@ -57,29 +57,26 @@
   
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
  -import org.apache.ojb.broker.util.configuration.Configurable;
  -import org.apache.ojb.broker.util.configuration.Configuration;
  -import org.apache.ojb.broker.util.configuration.ConfigurationException;
  -import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
  +import org.apache.ojb.broker.metadata.SequenceDescriptor;
  +import org.apache.ojb.broker.util.ClassHelper;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   
  -import java.lang.reflect.Constructor;
  -
   /**
  - * threadsafe factory class, creates <code>SequenceManager</code> instances.
  + * Threadsafe factory class, creates <code>SequenceManager</code> instances.
    * The implementation class is configured by the OJB.properties file.
    */
  -public class SequenceManagerFactory implements Configurable
  +public class SequenceManagerFactory
   {
       private static Logger log = LoggerFactory.getLogger(SequenceManagerFactory.class);
       private static SequenceManagerFactory singleton;
   
  -    private Class sequenceManagerClass;
  +    private Class defaultSeqManagerClass;
   
       public SequenceManagerFactory()
       {
  -        OjbConfigurator.getInstance().configure(this);
  +        defaultSeqManagerClass = SequenceManagerHighLowImpl.class;
  +        log.info("Default sequence manager class was " + defaultSeqManagerClass.getName());
       }
   
       public synchronized static SequenceManager getSequenceManager(PersistenceBroker broker)
  @@ -91,12 +88,6 @@
           return singleton.createNewSequenceManager(broker);
       }
   
  -    public void configure(Configuration pConfig) throws ConfigurationException
  -    {
  -        sequenceManagerClass = ((SequenceConfiguration) pConfig).getSequenceManagerClass();
  -        log.info("Use sequence manager class: " + sequenceManagerClass);
  -    }
  -
       private SequenceManager createNewSequenceManager(PersistenceBroker broker)
       {
           synchronized (singleton)
  @@ -104,10 +95,21 @@
               if (log.isDebugEnabled()) log.debug("create new sequence manager for broker " + broker);
               try
               {
  -                Class[] clazzargs = {PersistenceBroker.class};
  -                Constructor constructor = sequenceManagerClass.getConstructor(clazzargs);
  -                Object[] args = {broker};
  -                return (SequenceManager) constructor.newInstance(args);
  +                // first we use seqMan defined in the OJB.properties
  +                Class seqManClass = defaultSeqManagerClass;
  +                SequenceDescriptor sd = broker.serviceConnectionManager().getConnectionDescriptor().getSequenceDescriptor();
  +                if (sd != null && sd.getSequenceManagerClass() != null)
  +                {
  +                    // if a seqMan was defined in repository, use that
  +                    seqManClass = sd.getSequenceManagerClass();
  +                    if (log.isDebugEnabled())
  +                    {
  +                        log.debug("Jdbc-Connection-Descriptor '" +
  +                                broker.serviceConnectionManager().getConnectionDescriptor().getJcdAlias() +
  +                                "' use sequence manager: " + seqManClass);
  +                    }
  +                }
  +                return (SequenceManager) ClassHelper.newInstance(seqManClass, PersistenceBroker.class, broker);
               }
               catch (Exception ex)
               {
  
  
  
  1.7       +27 -34    jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHelper.java
  
  Index: SequenceManagerHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHelper.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- SequenceManagerHelper.java	24 Dec 2002 13:24:28 -0000	1.6
  +++ SequenceManagerHelper.java	9 Jan 2003 17:09:31 -0000	1.7
  @@ -51,12 +51,12 @@
           if we found a sequence name bound to the field descriptor
           via 'sequence-name' attribute we use that name
           */
  -        if(seqName != null && seqName.trim().length() != 0)
  +        if (seqName != null && seqName.trim().length() != 0)
           {
               return seqName;
           }
   
  -        Class topLevel = brokerForClass.getExtentClass(cldTargetClass.getClassOfObject());
  +        Class topLevel = brokerForClass.getTopLevelClass(cldTargetClass.getClassOfObject());
           ClassDescriptor cldTopLevel = brokerForClass.getClassDescriptor(topLevel);
           /**
            *
  @@ -72,7 +72,7 @@
            * the table name of the 'targetClass'.
            *
            */
  -        if(cldTopLevel.isExtent())
  +        if (cldTopLevel.isExtent())
           {
               seqName = brokerForClass.getClassDescriptor(((Class) cldTopLevel.getExtentClasses().
                       get(0))).getFullTableName();
  @@ -103,14 +103,14 @@
        */
       public static int getMaxForExtent(PersistenceBroker brokerForClass, FieldDescriptor field) throws PersistenceBrokerException
       {
  -        if(field == null)
  +        if (field == null)
           {
               log.error("Given FieldDescriptor was null, could not detect max value across all extents");
               return 0;
               // throw new PersistenceBrokerException("Given FieldDescriptor was null");
           }
           // first lookup top-level class
  -        Class topLevel = brokerForClass.getExtentClass(field.getClassDescriptor().getClassOfObject());
  +        Class topLevel = brokerForClass.getTopLevelClass(field.getClassDescriptor().getClassOfObject());
           return getMaxId(brokerForClass, topLevel, field);
       }
   
  @@ -163,40 +163,34 @@
       }
   
       /**
  -     * lookup current maximum value for a single autoincrement PK-field in
  -     * table cld.getFullTableName()
  +     * lookup current maximum value for a single field in
  +     * table the given class descriptor was associated.
        */
       private static int getMaxIdForClass(
               PersistenceBroker brokerForClass, ClassDescriptor cldForOriginalOrExtent, FieldDescriptor original)
               throws PersistenceBrokerException
       {
  -        FieldDescriptor field;
  -        /* TODO better solution
  -         now it's a little complicated, because object could have multiple autoincrement
  -         fields and multiple primary keys. So try to catch a FieldDescriptor of the
  -         extent class, which has the same field name as the original field descriptor.
  -        */
  -        FieldDescriptor fieldEqualsOriginal = cldForOriginalOrExtent.getFieldDescriptorByName(original.getPersistentField().getName());
  -//        FieldDescriptor fieldAutoincrement = cldForOriginalOrExtent.getAutoIncrementField();
  -        if(fieldEqualsOriginal != null && fieldEqualsOriginal.isPrimaryKey())
  -        {
  -            if(log.isDebugEnabled()) log.debug("Found pk field '"+
  -                    fieldEqualsOriginal.getPersistentField().getName() +
  -                    "' for class "+cldForOriginalOrExtent.getClassNameOfObject());
  -            field = fieldEqualsOriginal;
  -        }
  -//        else if(fieldAutoincrement != null && fieldAutoincrement.isPrimaryKey())
  -//        {
  -//            if(log.isDebugEnabled()) log.debug("Found autoincrement field '"+
  -//                    fieldAutoincrement.getPersistentField().getName() +
  -//                    "' for class "+cldForOriginalOrExtent.getClassNameOfObject());
  -//            field = fieldAutoincrement;
  -//        }
  +        FieldDescriptor field = null;
  +        if (!original.getClassDescriptor().equals(cldForOriginalOrExtent))
  +        {
  +            // check if extent match not the same table
  +            if (!original.getClassDescriptor().getFullTableName().equals(
  +                    cldForOriginalOrExtent.getFullTableName()))
  +            {
  +                // we have to look for id's in extent class table
  +                field = cldForOriginalOrExtent.getFieldDescriptorByName(original.getAttributeName());
  +            }
  +        }
           else
           {
  -            log.warn("Could not determine max id for class "+cldForOriginalOrExtent.getClassNameOfObject());
  +            field = original;
  +        }
  +        if (field == null)
  +        {
  +            // if null skip this call
               return 0;
           }
  +
           String column = field.getColumnName();
           int result = 0;
           ResultSet rs = null;
  @@ -214,7 +208,7 @@
           }
           catch (Exception e)
           {
  -            log.error("Cannot lookup max value from table " + table + " for column " + column +
  +            log.warn("Cannot lookup max value from table " + table + " for column " + column +
                       ", PB was " + brokerForClass + ", using jdbc-descriptor " +
                       brokerForClass.serviceConnectionManager().getConnectionDescriptor(), e);
           }
  @@ -225,9 +219,8 @@
                   if (rs != null) rs.close();
                   if (stmt != null) stmt.close();
               }
  -            catch (SQLException e)
  +            catch (SQLException ignore)
               {
  -                log.warn("Cleanup fails: " + e.getMessage());
               }
           }
           return result;
  
  
  
  1.13      +68 -16    jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHighLowImpl.java
  
  Index: SequenceManagerHighLowImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerHighLowImpl.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- SequenceManagerHighLowImpl.java	24 Dec 2002 13:24:28 -0000	1.12
  +++ SequenceManagerHighLowImpl.java	9 Jan 2003 17:09:31 -0000	1.13
  @@ -1,18 +1,51 @@
   package org.apache.ojb.broker.util.sequence;
   
  -import java.util.HashMap;
  -import java.util.Map;
  -
  +import org.apache.commons.lang.SystemUtils;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
  -import org.apache.commons.lang.SystemUtils;
  +
  +import java.util.HashMap;
  +import java.util.Map;
   
   /**
    * High/Low sequence manager implementation generates unique and continuous
    * id's (during runtime) by using sequences to avoid database access.
    *
  + * <p>
  + * Implementation configuration properties:
  + * </p>
  + *
  + * <table align="left" cellspacing="2" cellpadding="2" border="1" frame="box" rules="all">
  + * <tr>
  + *     <td><strong>Property Key</strong></td>
  + *     <td><strong>Property Values</strong></td>
  + * </tr>
  + * <tr>
  + *     <td>grabSize</td>
  + *     <td>
  + *         Integer entry determines the
  + *         number of IDs allocated within the
  + *         H/L sequence manager implementation.
  + *         Default was '20'.
  + *    </td>
  + * </tr>
  + * <tr>
  + *     <td>globalSequenceId</td>
  + *     <td>
  + *         If set 'true' implementation use global unique
  + *         id's for all fields. This modus is NOT extent aware!
  + *         Default was 'false'.
  + *    </td>
  + * </tr>
  + * </table>
  + *
  + * <br/>
  + * <br/>
  + * <br/>
  + * <br/>
  + *
    * @see org.apache.ojb.broker.util.sequence.SequenceManager
    * @see org.apache.ojb.broker.util.sequence.SequenceManagerFactory
    * @see org.apache.ojb.broker.util.sequence.SequenceGenerator
  @@ -25,22 +58,30 @@
   {
       private Logger log = LoggerFactory.getLogger(SequenceManagerHighLowImpl.class);
   
  +    public static final String PROPERTY_GRAB_SIZE = "grabSize";
  +    public static final String PROPERTY_GLOBAL_SEQUENCE_ID = "globalSequenceId";
  +
       private static Map sequencesMap = new HashMap();
  +    protected boolean useGlobalSequenceIdentities;
  +    protected int grabSize;
   
       public SequenceManagerHighLowImpl(PersistenceBroker broker)
       {
           super(broker);
  +        grabSize = new Integer(getConfigurationProperty(PROPERTY_GRAB_SIZE, "20")).intValue();
  +        useGlobalSequenceIdentities =
  +                new Boolean(getConfigurationProperty(PROPERTY_GLOBAL_SEQUENCE_ID, "false")).booleanValue();
       }
   
       /**
        * Gets a new uniqueId for the given Class and fieldname
        */
       public int getUniqueId(FieldDescriptor field)
  -             throws SequenceManagerException
  +            throws SequenceManagerException
       {
           HighLowSequence seq;
           String seqName;
  -        if (isGlobalSequenceIdentities())
  +        if (useGlobalSequenceIdentities)
           {
               seqName = SequenceManagerHelper.buildSequenceNameGlobal(getBrokerForClass(), field);
           }
  @@ -51,7 +92,7 @@
               if we found no sequence name for the given field, we try to
               assign a automatic generated sequence name.
               */
  -            if(seqName == null || seqName.trim().equals(""))
  +            if (seqName == null || seqName.trim().equals(""))
               {
                   seqName = SequenceManagerHelper.buildSequenceName(getBrokerForClass(), field);
                   field.setSequenceName(seqName);
  @@ -71,10 +112,16 @@
                   seq = new HighLowSequence();
                   seq.setTableName(seqName);
                   seq.setFieldName(field.getColumnName());
  -                seq.setGrabSize(getGrabSize());
  +                seq.setGrabSize(grabSize);
                   seq.setMaxKey(lastId);
  +
  +                /* @todo we need a callback mechanism to notify
  +                sequence manager if a rollback was done, because
  +                the obtained sequence entry in DB was rollback too and we
  +                have to remove current HighLowSequence*/
  +
                   seq = SequenceGenerator.getNextSequence(
  -                        getBrokerForClass(), seq, getKeyToSeparateSeqTable());
  +                        getBrokerForClass(), seq);
                   sequencesMap.put(seqName, seq);
               }
   
  @@ -82,20 +129,25 @@
               int id = seq.getNextId();
               if (id == 0)
               {
  +                /* @todo we need a callback mechanism to notify
  +                sequence manager if a rollback was done, because
  +                the obtained sequence entry in DB was rollback too and we
  +                have to remove current HighLowSequence*/
  +
                   //seq does not have reserved IDs => reload seq
                   seq = SequenceGenerator.getNextSequence(
  -                        getBrokerForClass(), seq, getKeyToSeparateSeqTable());
  +                        getBrokerForClass(), seq);
                   // replace old sequence!!
                   sequencesMap.put(seqName, seq);
                   id = seq.getNextId();
               }
               if (id == 0)
               {
  -                throw new SequenceManagerException("Sequence generation failed: "+
  -                        SystemUtils.LINE_SEPARATOR+"Sequence: " + seq +
  -                            ". Unable to build new ID, id was always 0." +
  -                        SystemUtils.LINE_SEPARATOR+"Thread: " + Thread.currentThread() +
  -                        SystemUtils.LINE_SEPARATOR+"PB: " + getBrokerForClass());
  +                throw new SequenceManagerException("Sequence generation failed: " +
  +                        SystemUtils.LINE_SEPARATOR + "Sequence: " + seq +
  +                        ". Unable to build new ID, id was always 0." +
  +                        SystemUtils.LINE_SEPARATOR + "Thread: " + Thread.currentThread() +
  +                        SystemUtils.LINE_SEPARATOR + "PB: " + getBrokerForClass());
               }
               else
               {
  
  
  
  1.6       +47 -4     jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerInMemoryImpl.java
  
  Index: SequenceManagerInMemoryImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerInMemoryImpl.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SequenceManagerInMemoryImpl.java	22 Nov 2002 00:13:59 -0000	1.5
  +++ SequenceManagerInMemoryImpl.java	9 Jan 2003 17:09:31 -0000	1.6
  @@ -6,9 +6,12 @@
   import java.util.HashMap;
   
   /**
  + * <p>
    * Very fast in memory sequence manager implementation, only the first
    * time an id was requested for a class, the manager query the database
  - * for the max id - all following request were performed in memory.
  + * for the max id in requested column - all following request were
  + * performed in memory.
  + * </p>
    * <b>Limitations:</b>
    * <ul type="disc">
    *	<li>do not use in client/server mode</li>
  @@ -16,6 +19,42 @@
    *	<li>do not use if other entities generate id's for objects</li>
    * </ul>
    *
  + * <p>
  + * Implementation configuration properties:
  + * </p>
  + *
  + * <table align="left" cellspacing="2" cellpadding="2" border="1" frame="box" rules="all">
  + * <tr>
  + *     <td><strong>Property Key</strong></td>
  + *     <td><strong>Property Values</strong></td>
  + * </tr>
  + * <tr>
  + *     <td>grabSize</td>
  + *     <td>
  + *         Integer entry determines the
  + *         number of IDs allocated within the
  + *         H/L sequence manager implementation.
  + *         Default was '20'.
  + *    </td>
  + * </tr>
  + * <tr>
  + *     <td>globalSequenceId</td>
  + *     <td>
  + *         If set 'true' implementation use global unique
  + *         id's for all fields. This modus is NOT extent aware!
  + *         Default was 'false'.
  + *    </td>
  + * </tr>
  + * </table>
  + *
  + * <br/>
  + * <br/>
  + * <br/>
  + * <br/>
  + * <br/>
  + * <br/>
  + * <br/>
  + *
    * @see org.apache.ojb.broker.util.sequence.SequenceManager
    * @see org.apache.ojb.broker.util.sequence.SequenceManagerFactory
    * @see org.apache.ojb.broker.util.sequence.SequenceGenerator
  @@ -26,18 +65,22 @@
    */
   public class SequenceManagerInMemoryImpl extends AbstractSequenceManager
   {
  +    public static final String PROPERTY_GLOBAL_SEQUENCE_ID = "globalSequenceId";
       private static HashMap sequenceNameKeyMap = new HashMap();
  +    protected boolean useGlobalSequenceIdentities;
   
       public SequenceManagerInMemoryImpl(PersistenceBroker broker)
       {
           super(broker);
  +        useGlobalSequenceIdentities =
  +                new Boolean(getConfigurationProperty(PROPERTY_GLOBAL_SEQUENCE_ID, "false")).booleanValue();
       }
   
       public int getUniqueId(FieldDescriptor field) throws SequenceManagerException
       {
           String seqName;
           int retId = 0;
  -        if (isGlobalSequenceIdentities())
  +        if (useGlobalSequenceIdentities)
           {
               seqName = SequenceManagerHelper.buildSequenceNameGlobal(getBrokerForClass(), field);
           }
  @@ -54,7 +97,7 @@
               if (currentId == null)
               {
                   currentId = new Integer(
  -                        SequenceManagerHelper.getMaxForExtent(getBrokerForClass(),  field));
  +                        SequenceManagerHelper.getMaxForExtent(getBrokerForClass(), field));
                   // check for start index
                   currentId = new Integer(currentId.intValue());
               }
  
  
  
  1.4       +104 -66   jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerNextValImpl.java
  
  Index: SequenceManagerNextValImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerNextValImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SequenceManagerNextValImpl.java	28 Dec 2002 12:58:30 -0000	1.3
  +++ SequenceManagerNextValImpl.java	9 Jan 2003 17:09:31 -0000	1.4
  @@ -54,38 +54,40 @@
    * <http://www.apache.org/>.
    */
   
  -import java.sql.ResultSet;
  -import java.sql.SQLException;
  -import java.sql.Statement;
  -
  +import org.apache.commons.lang.SystemUtils;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
   import org.apache.ojb.broker.query.Query;
   
  +import java.sql.ResultSet;
  +import java.sql.SQLException;
  +import java.sql.Statement;
  +
   /**
    * This SequenceManager implementation uses database
  - * sequence key generation (which was supported by
  - * e.g. Oracle, SAP DB, PostgreSQL).
  - * This class is responsible for creating new unique ID's
  - * for primary key columns.
  + * sequence key generation (e.g supported by
  + * Oracle, SAP DB, PostgreSQL, ...).
  + * This class is responsible for creating new unique ID's.
    * <br/>
  - * For using this sequence manager with your database it is mandatory
  - * to define a <code>sequence-name</code> field-descriptor attribute
  - * in the repository file.
  + * It is possible to define a <code>sequence-name</code>
  + * field-descriptor attribute in the repository file. If
  + * such an attribute was not found, the implementation build
  + * an extent aware sequence name by its own.
    * <br/>
  - * Keep in mind that you are responsible to be aware of extents,
  - * that is: if you ask for an uid for an interface with several
  + * Keep in mind when define a sequence name, that you are responsible
  + * to be aware of extents, that is: if you ask for an uid for an
  + * interface with several
    * implementor classes, or a baseclass with several subclasses the returned
    * uid have to be unique accross all tables representing objects of the
    * extent in question. Thus you have to use the same <code>sequence-name</code>
    * for all extents.
  - * <br/>
  - * If your database needs a specific sql statement to obtain the next
  - * sequence, extend this class and override the
  - * {@link #buildSqlStatement(String sequenceName)} method to build
  - * your own sql statement.
    *
  + * <p>
  + * Implementation configuration properties:
  + * </p>
  + * None.
  + * <br/>
    *
    * @author Edson Carlos Ericksson Richter
    * @author Rajeev Kaul
  @@ -95,70 +97,69 @@
    */
   public class SequenceManagerNextValImpl extends AbstractSequenceManager
   {
  -    public final static String SQL_SELECT = "select ";
  -    public final static String SQL_NEXTVAL = ".nextval from dual";
  +    private static final String SEQ_PREFIX = "SEQ_";
   
       /**
  -     * Public constructor
  +     *
        */
       public SequenceManagerNextValImpl(PersistenceBroker broker)
       {
           super(broker);
       }
   
  -    public int getUniqueId(FieldDescriptor field) throws SequenceManagerException
  -    {
  -        return getNextId(field);
  -    }
  -
       /**
  -     * Override this method to build your own sequence specific
  -     * sql statement - The standard sql statement was
  -     * "select SEQUENCE_NAME.nextval from dual".
  +     *
        */
  -    public String buildSqlStatement(String sequenceName)
  +    public int getUniqueId(FieldDescriptor field) throws SequenceManagerException
       {
  -        return new StringBuffer().
  -            append(SQL_SELECT).
  -            append(sequenceName).
  -            append(SQL_NEXTVAL).
  -            toString();
  +        int result = 0;
  +        // lookup sequence name
  +        String sequenceName = SEQ_PREFIX + SequenceManagerHelper.buildSequenceName(getBrokerForClass(), field);
  +        try
  +        {
  +            result = buildNextSequence(field.getClassDescriptor(), sequenceName);
  +        }
  +        catch (Exception e)
  +        {
  +            // maybe the sequence was not created
  +            try
  +            {
  +                createSequence(field.getClassDescriptor(), sequenceName);
  +            }
  +            catch (Exception e1)
  +            {
  +                throw new SequenceManagerException(
  +                        SystemUtils.LINE_SEPARATOR +
  +                        "Could not grab next id, failed with " + SystemUtils.LINE_SEPARATOR +
  +                        e.getMessage() + SystemUtils.LINE_SEPARATOR +
  +                        "Creation of new sequence failed with " +
  +                        SystemUtils.LINE_SEPARATOR + e1.getMessage() + SystemUtils.LINE_SEPARATOR
  +                        , e1);
  +            }
  +            try
  +            {
  +                result = buildNextSequence(field.getClassDescriptor(), sequenceName);
  +            }
  +            catch (Exception e1)
  +            {
  +                throw new SequenceManagerException("Could not grab next id, sequence seems to exist", e);
  +            }
  +        }
  +
  +        return result;
       }
   
  -    /**
  -     * Returns next Id get from "sequence sequence.NextVal from Dual".
  -     * Mount sequence name as:
  -     * Schema.SQ_tableName_fieldName. If you have a table named MY_TABLE
  -     * and the sequenced field is MY_FIELD on schema MY_SCHEMA, the command
  -     * to create the sequence is:
  -     * CREATE SEQUENCE MY_SCHEMA.SQ_MY_TABLE_MY_FIELD
  -     */
  -    private synchronized int getNextId(FieldDescriptor field)
  -            throws SequenceManagerException
  +    protected int buildNextSequence(ClassDescriptor cld, String sequenceName) throws Exception
       {
  -        int result = 0;
           ResultSet rs = null;
           Statement stmt = null;
  +
           try
           {
  -            ClassDescriptor cld = field.getClassDescriptor();
  -            // lookup sequence name as custom attribute on class descriptor level.
  -            String sequenceName = field.getSequenceName();
  -            if (sequenceName == null || sequenceName.length() == 0)
  -            {
  -                throw new SequenceManagerException(
  -                        "sequence-name attribute is not defined for field '" +
  -                        field.getAttributeName() + "' in the class descriptor for object "
  -                        + cld.getClassNameOfObject());
  -            }
               stmt = getBrokerForClass().serviceStatementManager().getGenericStatement(cld, Query.NOT_SCROLLABLE);
  -            rs = stmt.executeQuery(buildSqlStatement(sequenceName));
  +            rs = stmt.executeQuery(getPlatform().nextSequenceQuery(sequenceName));
               rs.next();
  -            result = rs.getInt(1);
  -        }
  -        catch (Exception e)
  -        {
  -            throw new SequenceManagerException("Could not grab next id",e);
  +            return rs.getInt(1);
           }
           finally
           {
  @@ -169,11 +170,48 @@
                   if (stmt != null)
                       stmt.close();
               }
  -            catch (SQLException e)
  +            catch (SQLException ignore)
  +            {
  +            }
  +        }
  +    }
  +
  +    protected void createSequence(ClassDescriptor cld, String sequenceName) throws Exception
  +    {
  +        Statement stmt = null;
  +        try
  +        {
  +            stmt = getBrokerForClass().serviceStatementManager().getGenericStatement(cld, Query.NOT_SCROLLABLE);
  +            stmt.execute(getPlatform().dropSequenceQuery(sequenceName));
  +        }
  +        catch (Exception ignore)
  +        {
  +        }
  +        finally
  +        {
  +            try
  +            {
  +                if (stmt != null) stmt.close();
  +            }
  +            catch (SQLException ignore)
  +            {
  +            }
  +        }
  +
  +        try
  +        {
  +            stmt = getBrokerForClass().serviceStatementManager().getGenericStatement(cld, Query.NOT_SCROLLABLE);
  +            stmt.execute(getPlatform().createSequenceQuery(sequenceName));
  +        }
  +        finally
  +        {
  +            try
  +            {
  +                if (stmt != null) stmt.close();
  +            }
  +            catch (SQLException ignore)
               {
  -                throw new SequenceManagerException(e);
               }
  -            return result;
           }
       }
   }
  
  
  
  1.1                  jakarta-ojb/src/java/org/apache/ojb/broker/util/sequence/SequenceManagerSeqHiLoImpl.java
  
  Index: SequenceManagerSeqHiLoImpl.java
  ===================================================================
  package org.apache.ojb.broker.util.sequence;
  
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.metadata.FieldDescriptor;
  
  /**
   * <p>
   * A High/Low database sequence based implementation.
   * See {@link org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl}
   * for more information.
   * </p>
   *
   * <b>Limitations:</b>
   * <ul type="disc">
   *	<li>do not use when other applications use the database sequence ditto</li>
   * </ul>
   *
   * <p>
   * Implementation configuration properties:
   * </p>
   *
   * <table align="left" cellspacing="2" cellpadding="2" border="1" frame="box" rules="all">
   * <tr>
   *     <td><strong>Property Key</strong></td>
   *     <td><strong>Property Values</strong></td>
   * </tr>
   * <tr>
   *     <td>grabSize</td>
   *     <td>
   *         Integer entry determines the
   *         number of IDs allocated within the
   *         H/L sequence manager implementation.
   *         Default was '20'.
   *    </td>
   * </tr>
   * </table>
   *
   * <br/>
   * <br/>
   * <br/>
   * <br/>
   *
   * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
   * @version $Id: SequenceManagerSeqHiLoImpl.java,v 1.1 2003/01/09 17:09:31 arminw Exp $
   */
  public class SequenceManagerSeqHiLoImpl extends SequenceManagerNextValImpl
  {
      public static final String PROPERTY_GRAB_SIZE = SequenceManagerHighLowImpl.PROPERTY_GRAB_SIZE;
      protected int grabSize;
  
      private int counter;
      private int maxVal;
  
      public SequenceManagerSeqHiLoImpl(PersistenceBroker broker)
      {
          super(broker);
          grabSize = counter = new Integer(getConfigurationProperty(PROPERTY_GRAB_SIZE, "20")).intValue();
      }
  
      public int getUniqueId(FieldDescriptor field) throws SequenceManagerException
      {
          if (counter == grabSize)
          {
              maxVal = grabSize * (super.getUniqueId(field) + 1);
              counter = 0;
          }
          return maxVal + counter++;
      }
  }