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