You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mi...@apache.org on 2011/08/02 00:11:47 UTC

svn commit: r1152952 - in /openjpa/branches/1.2.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/ ...

Author: mikedd
Date: Mon Aug  1 22:11:45 2011
New Revision: 1152952

URL: http://svn.apache.org/viewvc?rev=1152952&view=rev
Log:
OPENJPA-1376: Backported trunk changes to 1.2.x where possible, made code gated by a system property.

Added:
    openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java   (with props)
    openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java   (with props)
Modified:
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java
    openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
    openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
    openjpa/branches/1.2.x/openjpa-project/src/doc/manual/jpa_overview_mapping.xml
    openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
    openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_optimization.xml
    openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_runtime.xml

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java Mon Aug  1 22:11:45 2011
@@ -54,6 +54,8 @@ import serp.util.Strings;
 /**
  * {@link JDBCSeq} implementation that uses a database sequences
  * to generate numbers.
+ * Supports allocation (caching). In order for allocation to work properly, the database sequence must be defined
+ * with INCREMENT BY value equal to allocate * increment.
  *
  * @see JDBCSeq
  * @see AbstractJDBCSeq
@@ -72,9 +74,12 @@ public class NativeJDBCSeq
     private String _seqName = "OPENJPA_SEQUENCE";
     private int _increment = 1;
     private int _initial = 1;
-    private int _allocate = 0;
+    private int _allocate = 50;
     private Sequence _seq = null;
     private String _select = null;
+    private long _nextValue = 0;
+    private long _maxValue = -1;
+    
 
     // for deprecated auto-configuration support
     private String _format = null;
@@ -194,30 +199,76 @@ public class NativeJDBCSeq
 
     public void endConfiguration() {
         buildSequence();
-
-        DBDictionary dict = _conf.getDBDictionaryInstance();
-        if (_format == null) {
-            _format = dict.nextSequenceQuery;
-            if (_format == null)
-                throw new MetaDataException(_loc.get("no-seq-sql", _seqName));
-        }
+        
         if (_tableName == null)
             _tableName = "DUAL";
 
+        DBDictionary dict = _conf.getDBDictionaryInstance();
         String name = dict.getFullName(_seq);
-        Object[] subs = (_subTable) ? new Object[]{ name, _tableName }
+        
+        if (dict.useNativeSequenceCache){
+            if (_format == null) {
+            	_format = dict.nextSequenceQuery;
+            	if (_format == null)
+            		throw new MetaDataException(_loc.get("no-seq-sql", _seqName));
+            }
+            
+            Object[] subs = (_subTable) ? new Object[]{ name, _tableName }
             : new Object[]{ name };
-        _select = MessageFormat.format(_format, subs);
+            _select = MessageFormat.format(_format, subs);
+        }
+        else {           
+        	String format = dict.nextSequenceQuery;
+            if (format == null) {
+                throw new MetaDataException(_loc.get("no-seq-sql", _seqName));
+            }
+            
+            // Increment step is needed for Firebird which uses non-standard sequence fetch syntax.
+            // Use String.valueOf to get rid of possible locale-specific number formatting.
+            _select = MessageFormat.format(format, new Object[]{name, String.valueOf(_allocate * _increment)});            
+        }       
         
         type = dict.nativeSequenceType;
     }
     
     @Override
-    protected Object nextInternal(JDBCStore store, ClassMapping mapping)
+    protected synchronized Object nextInternal(JDBCStore store, ClassMapping mapping)
         throws SQLException {
+        DBDictionary dict = _conf.getDBDictionaryInstance();
+        
+        //To maintain existing behavior call allocateInternal to get the next 
+        //sequence value, which it stores in _nextValue, and simply return the value.
+        if (dict.useNativeSequenceCache){
+        	allocateInternal(0, store, mapping);
+        	return _nextValue;
+        }
+        
+        if (_nextValue < _maxValue) {
+            long result = _nextValue;
+            _nextValue += _increment;
+            return result;
+        }
+
+        allocateInternal(0, store, mapping);
+        long result = _nextValue;
+        _nextValue += _increment;
+        return result;
+    }
+
+    /**
+     * Allocate additional sequence values.
+     * @param additional ignored - the allocation size is fixed and determined by allocate and increment properties. 
+     * @param store used to obtain connection
+     * @param mapping ignored
+     */
+    @Override
+    protected synchronized void allocateInternal(int additional, JDBCStore store, ClassMapping mapping)
+        throws SQLException {
+    	
         Connection conn = getConnection(store);
         try {
-            return Numbers.valueOf(getSequence(conn));
+            _nextValue = Numbers.valueOf(getSequence(conn));
+            _maxValue = _nextValue + _allocate * _increment;            
         } finally {
             closeConnection(conn);
         }
@@ -281,9 +332,7 @@ public class NativeJDBCSeq
         ResultSet rs = null;
         try {
             stmnt = conn.prepareStatement(_select);
-            synchronized(this) {
-                rs = stmnt.executeQuery();
-            }
+            rs = stmnt.executeQuery();
             if (rs.next())
                 return rs.getLong(1);
 
@@ -308,13 +357,12 @@ public class NativeJDBCSeq
      *  Where the following options are recognized.
      * <ul>
      * <li><i>-properties/-p &lt;properties file or resource&gt;</i>: The
-     * path or resource name of a OpenJPA properties file containing
-     * information such as the license key	and connection data as
+     * path or resource name of an OpenJPA properties file containing
+     * information such as connection data as
      * outlined in {@link JDBCConfiguration}. Optional.</li>
      * <li><i>-&lt;property name&gt; &lt;property value&gt;</i>: All bean
      * properties of the OpenJPA {@link JDBCConfiguration} can be set by
-     * using their	names and supplying a value. For example:
-     * <code>-licenseKey adslfja83r3lkadf</code></li>
+     * using their names and supplying a value.</li>
      * </ul>
      *  The various actions are as follows.
      * <ul>
@@ -354,7 +402,7 @@ public class NativeJDBCSeq
     }
 
     /**
-     * Run the tool. Return false if an invalid option was given.
+     * Run the tool. Returns false if an invalid option was given.
      */
     public static boolean run(JDBCConfiguration conf, String[] args,
         String action)

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java Mon Aug  1 22:11:45 2011
@@ -203,13 +203,16 @@ public class DB2Dictionary
             selectSQL.append(")");
         }
     }
-
-    public String[] getCreateSequenceSQL(Sequence seq) {
-        String[] sql = super.getCreateSequenceSQL(seq);
-        if (seq.getAllocate() > 1)
-            sql[0] += " CACHE " + seq.getAllocate();
-        return sql;
-    }
+    
+    public String[] getCreateSequenceSQL(Sequence seq) {    
+    	String[] sql = super.getCreateSequenceSQL(seq);
+    	
+    	if (seq.getAllocate() > 1 && useNativeSequenceCache){    	
+    		sql[0] += " CACHE " + seq.getAllocate();
+    	}
+    	
+    	return sql;
+    }   
 
     protected String getSequencesSQL(String schemaName, String sequenceName) {
         StringBuffer buf = new StringBuffer();

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Mon Aug  1 22:11:45 2011
@@ -334,8 +334,9 @@ public class DBDictionary
     public String sequenceNameSQL = null;
     // most native sequences can be run inside the business transaction
     public int nativeSequenceType= Seq.TYPE_TRANSACTIONAL;
+    public boolean useNativeSequenceCache = true;
 
-    protected JDBCConfiguration conf = null;
+	protected JDBCConfiguration conf = null;
     protected Log log = null;
     protected boolean connected = false;
     protected boolean isJDBC3 = false;
@@ -3157,8 +3158,14 @@ public class DBDictionary
         buf.append(getFullName(seq));
         if (seq.getInitialValue() != 0)
             buf.append(" START WITH ").append(seq.getInitialValue());
-        if (seq.getIncrement() > 1)
-            buf.append(" INCREMENT BY ").append(seq.getIncrement());
+        
+        if (seq.getIncrement() > 1 && useNativeSequenceCache){
+        	buf.append(" INCREMENT BY ").append(seq.getIncrement());
+        }
+        else if ((seq.getIncrement() > 1) || (seq.getAllocate() > 1)){
+            buf.append(" INCREMENT BY ").append(seq.getIncrement() * seq.getAllocate());
+        }
+        
         return new String[]{ buf.toString() };
     }
 

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java Mon Aug  1 22:11:45 2011
@@ -56,7 +56,6 @@ import org.apache.openjpa.lib.util.J2DoP
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.util.StoreException;
 import org.apache.openjpa.util.UserException;
-
 import serp.util.Numbers;
 
 /**
@@ -929,12 +928,15 @@ public class OracleDictionary
             sql[create.length + i] = (String) seqs.get(i);
         return sql;
     }
-
-    public String[] getCreateSequenceSQL(Sequence seq) {
-        String[] sql = super.getCreateSequenceSQL(seq);
-        if (seq.getAllocate() > 1)
-            sql[0] += " CACHE " + seq.getAllocate();
-        return sql;
+    
+    public String[] getCreateSequenceSQL(Sequence seq) {    
+    	String[] sql = super.getCreateSequenceSQL(seq);
+    	
+    	if (seq.getAllocate() > 1 && useNativeSequenceCache){
+    		sql[0] += " CACHE " + seq.getAllocate();
+    	}
+    	
+    	return sql;    	
     }
 
     protected String getSequencesSQL(String schemaName, String sequenceName) {

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java Mon Aug  1 22:11:45 2011
@@ -277,11 +277,15 @@ public class PostgresDictionary
 
     public String[] getCreateSequenceSQL(Sequence seq) {
         String[] sql = super.getCreateSequenceSQL(seq);
-        if (seq.getAllocate() > 1)
+        
+        if (seq.getAllocate() > 1 && useNativeSequenceCache){
             sql[0] += " CACHE " + seq.getAllocate();
+        }
+        
         return sql;
     }
 
+    
     protected boolean supportsDeferredUniqueConstraints() {
         // Postgres only supports deferred foreign key constraints.
         return false;

Added: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java?rev=1152952&view=auto
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java (added)
+++ openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java Mon Aug  1 22:11:45 2011
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="primary_entityE2")
+public class EntityE2 {
+    @Id
+    @SequenceGenerator(name="entityE2_seq_gen_name", 
+                       sequenceName="entityE2_seq_gen")
+    @GeneratedValue(strategy=GenerationType.SEQUENCE, 
+        generator="entityE2_seq_gen_name")
+    private int id;
+    @Column(name="e_name")
+    private String name;
+    
+    public EntityE2(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * @return the id
+     */
+    public int getId() {
+        return id;
+    }
+    /**
+     * @param id the id to set
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+}

Propchange: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/EntityE2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java?rev=1152952&view=auto
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java (added)
+++ openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java Mon Aug  1 22:11:45 2011
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.generationtype;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+public class TestNativeSeqGenerator extends SQLListenerTestCase {
+    OpenJPAEntityManager em;
+    JDBCConfiguration conf;
+    DBDictionary dict;
+    
+    EntityE2 entityE2;
+	private boolean supportsNativeSequence;
+    
+    @Override
+    public void setUp() throws Exception {
+        super.setUp(EntityE2.class,DROP_TABLES);
+        assertNotNull(emf);
+        conf = (JDBCConfiguration) emf.getConfiguration();
+        dict = conf.getDBDictionaryInstance();
+        //Run the tests only if the given DB supports Native Sequences.
+        supportsNativeSequence = dict.nextSequenceQuery != null; 
+        if (supportsNativeSequence) {
+            em = emf.createEntityManager();
+            assertNotNull(em);
+        } else {
+            getLog().trace(this + " is disabled because " + dict.getClass().getSimpleName() +
+                " does not support native sequences.");
+        }
+    }
+    
+    public void createEntityE2() {
+        entityE2 = new EntityE2("e name");
+    }
+    
+    public void testGetIdGeneratorSeqGen() {
+    	if (supportsNativeSequence){
+	        createEntityE2();
+	        em.getTransaction().begin();
+	        em.persist(entityE2);
+	        em.getTransaction().commit();
+	        int genId = entityE2.getId();        
+	        int nextId = (int)((Long)em.getIdGenerator(EntityE2.class).next()).longValue();
+	        assertTrue("Next value should depend on previous genid", nextId >= genId + 1);
+	        em.close();
+    	}
+    }
+
+    /**
+     * Asserts native sequence generator allocates values in memory
+     * and requests sequence values from database only when necessary.
+     */
+    public void testAllocationSize() {
+        //Run this test only if the user has elected to not use the Native Sequence Cache.
+    	if (supportsNativeSequence && !dict.useNativeSequenceCache){
+	        // Turn off statement batching for easier INSERT counting.
+	        dict.setBatchLimit(0);
+	        em.getTransaction().begin();
+	        resetSQL();
+	        for (int i = 0; i < 51; i++) {
+	            createEntityE2();
+	            em.persist(entityE2);
+	        }
+	        em.getTransaction().commit();
+	
+	        // Since allocationSize has a default of 50, we expect 2 sequence fetches and 51 INSERTs.
+	        assertEquals("53 statements should be executed.", 53, getSQLCount());
+	        String[] statements = new String[53];
+	        statements[0] = ".*";
+	        statements[1] = ".*";
+	        for (int i = 2; i < 53; i++) {
+	            statements[i] = "INSERT .*";
+	        }
+	        assertAllExactSQLInOrder(statements);
+	        em.close();
+    	}
+    }
+}

Propchange: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java (original)
+++ openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java Mon Aug  1 22:11:45 2011
@@ -34,7 +34,6 @@ public abstract class SQLListenerTestCas
     extends SingleEMFTestCase {
     private static String _nl = System.getProperty("line.separator");
     protected List<String> sql = new ArrayList<String>();
-    protected int sqlCount;
     
     @Override
     public void setUp(Object... props) {
@@ -97,17 +96,17 @@ public abstract class SQLListenerTestCas
      * Gets the number of SQL issued since last reset.
      */
     public int getSQLCount() {
-    	return sqlCount;
+    	return sql.size();
     }
     
     /**
      * Resets SQL count.
      * @return number of SQL counted since last reset.
      */
-    public int resetSQLCount() {
-    	int tmp = sqlCount;
-    	sqlCount = 0;
-    	return tmp;
+    public int resetSQL() {
+        int tmp = sql.size();
+        sql.clear();
+        return tmp;
     }
 
     public class Listener
@@ -117,7 +116,6 @@ public abstract class SQLListenerTestCas
         public void beforeExecuteStatement(JDBCEvent event) {
             if (event.getSQL() != null && sql != null) {
                 sql.add(event.getSQL());
-                sqlCount++;
             }
 		}
 	}
@@ -145,4 +143,44 @@ public abstract class SQLListenerTestCas
             fail(sb.toString());
         }
     }
+
+    /**
+     * Confirm the list of expected SQL expressions have been executed in the
+     * exact number and order specified.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertAllExactSQLInOrder(String... expected) {
+        assertSQLInOrder(true, expected);
+    }
+
+    private void assertSQLInOrder(boolean exact, String... expected) {
+        boolean match = false;
+        int sqlSize = sql.size();
+        if (expected.length <= sqlSize) {
+            int hits = 0;
+            for (String executedSQL : sql) {
+                if (executedSQL.matches(expected[hits])) {
+                    if (++hits == expected.length)
+                        break;
+                }
+            }
+            match = hits == (exact ? sqlSize : expected.length);
+        }
+
+        if (!match) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Did not find SQL in expected order : ").append(_nl);
+            for (String s : expected) {
+                sb.append(s).append(_nl);
+            }
+
+            sb.append("SQL Statements issued : ");
+            for (String s : sql) {
+                sb.append(s).append(_nl);
+            }
+            fail(sb.toString());
+        }
+    }
 }

Modified: openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java (original)
+++ openjpa/branches/1.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java Mon Aug  1 22:11:45 2011
@@ -19,6 +19,7 @@
 package org.apache.openjpa.persistence.test;
 
 import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
 
 /**
@@ -123,4 +124,9 @@ public abstract class SingleEMFTestCase
     public int count(Class c) {
     	return count(c.getSimpleName());
     }
+    
+    protected Log getLog() {
+        return emf.getConfiguration().getLog("Tests");
+    }
+    
 }

Modified: openjpa/branches/1.2.x/openjpa-project/src/doc/manual/jpa_overview_mapping.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-project/src/doc/manual/jpa_overview_mapping.xml?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-project/src/doc/manual/jpa_overview_mapping.xml (original)
+++ openjpa/branches/1.2.x/openjpa-project/src/doc/manual/jpa_overview_mapping.xml Mon Aug  1 22:11:45 2011
@@ -960,10 +960,11 @@ default.
                             allocationSize property
                         </secondary>
                     </indexterm>
-<literal>int allocationSize</literal>: Some databases can pre-allocate groups
-of sequence values. This allows the database to service sequence requests from
-cache, rather than physically incrementing the sequence with every request. This
-allocation size defaults to 50.
+<literal>int allocationSize</literal>: The number of values to allocate in
+memory for each trip to the database. Allocating values in memory allows the JPA
+runtime to avoid accessing the database for every sequence request.
+This number also specifies the amount that the sequence value is incremented
+each time the sequence is accessed. Defaults to 50.
                     </para>
                 </listitem>
             </itemizedlist>

Modified: openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml (original)
+++ openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml Mon Aug  1 22:11:45 2011
@@ -1656,8 +1656,9 @@ table name. Defaults to 128.
                     </indexterm>
 <literal>NextSequenceQuery</literal>: A SQL string for obtaining a native
 sequence value. May use a placeholder of <literal>{0}</literal> for the variable
-sequence name. Defaults to a database-appropriate value.  For example, 
-<literal>"SELECT {0}.NEXTVAL FROM DUAL"</literal> for Oracle.
+sequence name and <literal>{1}</literal> for sequence increment.
+Defaults to a database-appropriate value. For example, 
+<literal>"SELECT {0}.NEXTVAL FROM DUAL"</literal> for Oracle database.
                     </para>
                 </listitem>
                 <listitem id="DBDictionary.NullTypeName">

Modified: openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_optimization.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_optimization.xml?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_optimization.xml (original)
+++ openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_optimization.xml Mon Aug  1 22:11:45 2011
@@ -295,8 +295,7 @@ it can become a factor.
                     </entry>
                     <entry colname="desc">
 For applications that perform large bulk inserts, the retrieval of sequence 
-numbers can be a bottleneck.  Increasing sequence increments and using 
-table-based rather than native database sequences can reduce or eliminate 
+numbers can be a bottleneck. Increasing sequence allocation sizes can reduce or eliminate 
 this bottleneck. In some cases, implementing your own sequence factory can 
 further optimize sequence number retrieval.
                     </entry>

Modified: openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_runtime.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_runtime.xml?rev=1152952&r1=1152951&r2=1152952&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_runtime.xml (original)
+++ openjpa/branches/1.2.x/openjpa-project/src/doc/manual/ref_guide_runtime.xml Mon Aug  1 22:11:45 2011
@@ -1620,8 +1620,11 @@ properties:
                     </listitem>
                     <listitem>
                         <para>
-<literal>Allocate</literal>: Some database can allocate values in-memory to
-service subsequent sequence requests faster.
+<literal>Allocate</literal>: The number of values to allocate on each database
+trip. Defaults to 50, meaning the class will set aside the next 50 numbers each
+time it accesses the sequence, which in turn means it only has to make a
+database trip to get new sequence numbers once every 50 sequence number
+requests.
                         </para>
                     </listitem>
                 </itemizedlist>