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++;
}
}