From 5fafa802aa71b6f07aa99570c9ba4e73245e937c Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Wed, 9 Nov 2011 19:12:34 +0000 Subject: [PATCH] OPENJPA-2069 Update db sequence's INCREMENT BY value to match the allocationSize specified in @SequenceGenerator git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1199921 13f79535-47bb-0310-9956-ffa450edef68 --- .../openjpa/jdbc/kernel/NativeJDBCSeq.java | 40 +++++++++++++++---- .../apache/openjpa/jdbc/sql/DBDictionary.java | 36 ++++++++++------- .../TestNativeSeqGenerator.java | 9 +++-- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java index 955b7f1e5..9ede96ab3 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java @@ -80,7 +80,9 @@ public class NativeJDBCSeq private long _maxValue = -1; private DBIdentifier _schema = DBIdentifier.NULL; - + + private boolean alterIncrementBy = false; + /** * The sequence name. Defaults to OPENJPA_SEQUENCE. */ @@ -191,13 +193,13 @@ public class NativeJDBCSeq @Override protected synchronized Object nextInternal(JDBCStore store, ClassMapping mapping) throws SQLException { - if (_nextValue < _maxValue) { - long result = _nextValue; - _nextValue += _increment; - return result; + if (!alterIncrementBy) { + allocateInternal(0, store, mapping); + alterIncrementBy = true; + } + if (_nextValue >= _maxValue) { + allocateInternal(0, store, mapping); } - - allocateInternal(0, store, mapping); long result = _nextValue; _nextValue += _increment; return result; @@ -214,6 +216,10 @@ public class NativeJDBCSeq throws SQLException { Connection conn = getConnection(store); try { + if (!alterIncrementBy) { + DBDictionary dict = _conf.getDBDictionaryInstance(); + udpateSql(conn, dict.getAlterSequenceSQL(_seq)); + } _nextValue = getSequence(conn); _maxValue = _nextValue + _allocate * _increment; } finally { @@ -305,6 +311,26 @@ public class NativeJDBCSeq } } + private int udpateSql(Connection conn, String sql) throws SQLException { + DBDictionary dict = _conf.getDBDictionaryInstance(); + PreparedStatement stmnt = null; + int rc = -1; + try { + stmnt = conn.prepareStatement(sql); + dict.setTimeouts(stmnt, _conf, false); + rc = stmnt.executeUpdate(); + } finally { + // clean up our resources + if (stmnt != null) { + try { + stmnt.close(); + } catch (SQLException se) { + } + } + } + return rc; + } + ///////// // Main ///////// diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java index dc4270877..07df88169 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java @@ -3406,28 +3406,36 @@ public class DBDictionary * [ INCREMENT BY <increment>] by default. */ public String[] getCreateSequenceSQL(Sequence seq) { + return commonCreateAlterSequenceSQL(seq, true); + } + + public String getAlterSequenceSQL(Sequence seq) { + return commonCreateAlterSequenceSQL(seq, false)[0]; + } + + private String[] commonCreateAlterSequenceSQL(Sequence seq, boolean create) { if (nextSequenceQuery == null) return null; - //We need a place to detect if the user is setting the 'useNativeSequenceCache' property. - //While in previous releases this property had meaning, it is no longer useful - //given the code added via OPENJPA-1327. As such, we need to warn user's the - //property no longer has meaning. While it would be nice to have a better way - //to detect if the useNativeSequenceCache property has been set, the best we can do - //is detect the variable in this code path as this is the path a user's code - //would go down if they are still executing code which actually made use of - //the support provided via setting useNativeSequenceCache. - if (!useNativeSequenceCache && logNativeSequenceCacheWarning){ - log.warn(_loc.get("sequence-cache-warning")); - logNativeSequenceCacheWarning=false; - } + //We need a place to detect if the user is setting the 'useNativeSequenceCache' property. + //While in previous releases this property had meaning, it is no longer useful + //given the code added via OPENJPA-1327. As such, we need to warn user's the + //property no longer has meaning. While it would be nice to have a better way + //to detect if the useNativeSequenceCache property has been set, the best we can do + //is detect the variable in this code path as this is the path a user's code + //would go down if they are still executing code which actually made use of + //the support provided via setting useNativeSequenceCache. + if (!useNativeSequenceCache && logNativeSequenceCacheWarning){ + log.warn(_loc.get("sequence-cache-warning")); + logNativeSequenceCacheWarning=false; + } StringBuilder buf = new StringBuilder(); - buf.append("CREATE SEQUENCE "); + buf.append(create ? "CREATE" : "ALTER").append(" SEQUENCE "); String seqName = checkNameLength(getFullName(seq), maxTableNameLength, "long-seq-name"); buf.append(seqName); - if (seq.getInitialValue() != 0) + if (create && seq.getInitialValue() != 0) buf.append(" START WITH ").append(seq.getInitialValue()); if ((seq.getIncrement() > 1) || (seq.getAllocate() > 1)) buf.append(" INCREMENT BY ").append(seq.getIncrement() * seq.getAllocate()); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java index b63bbccf2..67d93a929 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestNativeSeqGenerator.java @@ -79,11 +79,12 @@ public class TestNativeSeqGenerator extends SQLListenerTestCase { 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] = ".*"; + assertEquals("54 statements should be executed.", 54, getSQLCount()); + String[] statements = new String[54]; + statements[0] = "ALTER .*"; statements[1] = ".*"; - for (int i = 2; i < 53; i++) { + statements[2] = ".*"; + for (int i = 3; i < 54; i++) { statements[i] = "INSERT .*"; } assertAllExactSQLInOrder(statements);