Author: johnthuss Date: Wed Dec 26 20:52:44 2012 New Revision: 1426022 URL: http://svn.apache.org/viewvc?rev=1426022&view=rev Log: Improve implementation of JdbcPkGenerator.generatePk (CAY 1782)
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/dba/ConcurrentPkGeneratorTest.java Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java?rev=1426022&r1=1426021&r2=1426022&view=diff ============================================================================== --- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java (original) +++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java Wed Dec 26 20:52:44 2012 @@ -26,14 +26,12 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; +import java.util.HashSet; import java.util.List; import java.util.Queue; -import java.util.SortedSet; -import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; @@ -252,7 +250,7 @@ public class JdbcPkGenerator implements else cacheSize = pkCacheSize; - long value; + Long value; // if no caching, always generate fresh if (cacheSize <= 1) { @@ -270,43 +268,24 @@ public class JdbcPkGenerator implements } } - if (pks.isEmpty()) { - long val = longPkFromDatabase(node, entity); - Queue<Long> nextPks = mkRange(val, val + cacheSize - 1); - int iterations = 0; - while (!pkCache.replace(entity.getName(), pks, nextPks) && iterations < 999) { - pks = pkCache.get(entity.getName()); // the cache for this entity has changed, so re-fetch it then update - Queue<Long> previousPlusNext = new ConcurrentLinkedQueue<Long>(pks); - previousPlusNext.addAll(nextPks); - nextPks = previousPlusNext; - iterations++; - } - if (iterations >= 999) { - throw new IllegalStateException("Unable to add new primary keys to the cache for entity " + entity.getName()); + value = pks.poll(); + if (value == null) { + value = longPkFromDatabase(node, entity); + for (long i = value+1; i < value + cacheSize; i++) { + pks.add(i); } - pks = nextPks; } - - value = pks.poll(); } if (pk.getType() == Types.BIGINT) { - return Long.valueOf(value); + return value; } else { // leaving it up to the user to ensure that PK does not exceed max int... - return Integer.valueOf((int) value); + return value.intValue(); } } - private Queue<Long> mkRange(long min, long max) { - Queue<Long> result = new ConcurrentLinkedQueue<Long>(); - for (long i = min; i <= max; i++) { - result.add(i); - } - return result; - } - /** * Performs primary key generation ignoring cache. Generates a range of primary keys * as specified by "pkCacheSize" bean property. Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/dba/ConcurrentPkGeneratorTest.java URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/dba/ConcurrentPkGeneratorTest.java?rev=1426022&r1=1426021&r2=1426022&view=diff ============================================================================== --- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/dba/ConcurrentPkGeneratorTest.java (original) +++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/dba/ConcurrentPkGeneratorTest.java Wed Dec 26 20:52:44 2012 @@ -48,7 +48,7 @@ public class ConcurrentPkGeneratorTest e */ public void testConcurrentInserts() throws Exception { final DataMap dataMap = runtime.getDataDomain().getDataMap("qualified"); - + // clear out the table ObjectContext context = runtime.getContext(); List<Qualified1> qualified1s = context.select(SelectQuery.query(Qualified1.class, null)); @@ -102,13 +102,14 @@ public class ConcurrentPkGeneratorTest e } }); - int lastPk = Cayenne.intPKForObject(qualified1s.get(0)) - 1; - for (Qualified1 qualified1 : qualified1s) { - if (lastPk+1 != Cayenne.intPKForObject(qualified1)) { - fail("Found gap in sequence number: " + lastPk + " - " + Cayenne.intPKForObject(qualified1)); - } - lastPk++; - } + // PKs will be used in order most of the time, but the implementation doesn't guarantee it. +// int lastPk = Cayenne.intPKForObject(qualified1s.get(0)) - 1; +// for (Qualified1 qualified1 : qualified1s) { +// if (lastPk+1 != Cayenne.intPKForObject(qualified1)) { +// fail("Found gap in sequence number: " + lastPk + " - " + Cayenne.intPKForObject(qualified1)); +// } +// lastPk++; +// } } }