Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » manually allocate a @GeneratedValue
manually allocate a @GeneratedValue [message #488350] Mon, 28 September 2009 11:16 Go to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
I've been wrestling with locking and EclipseLink's caching for a few weeks now and decided to implement my allocation locking using native queries. This however involves creating new entities that get their PK's from a sequence table so now I need to allocate a new value manually.

Is there a easy way to invoke the "get me the next PK for xxx"?

Tom
Re: manually allocate a @GeneratedValue [message #488364 is a reply to message #488350] Mon, 28 September 2009 12:39 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> Is there a easy way to invoke the "get me the next PK for xxx"?

This does the job, but I hate having duplicate code and the allocating by Eclipselink may be done through a different connection, thus causing locking conflicts. So I still prefer using Eclipselink's code.

/**
* Allocate a block, return the highest allocated key.
* So if the block size is 3 and returned is 100, then 98, 99 and 100 are allocated.
*
* @param entityManager
* @param countColumnName
* @param nameColumnName
* @param sequenceTableName
* @param name
* @param blocksize
* @return the highest allocated value
*/
static public BigInteger allocateValueFromSequence(EntityManager entityManager, String countColumnName, String nameColumnName, String sequenceTableName, String name, int blocksize)
{
Query lQuery;

// number of attempts
for (int lAttempt = 0; lAttempt < 10; lAttempt++)
{
// get the last issued PK
lQuery = entityManager.createNativeQuery("select " + countColumnName + " from " + sequenceTableName + " where " + nameColumnName + "=?");
lQuery.setParameter(1, name);
BigInteger lLastPK = new BigInteger( JpaUtil.getSingleResultOrNull(lQuery).toString() );

// calculate the new "last issued PK"
BigInteger lAllocatedPK = lLastPK.add( BigInteger.valueOf(blocksize) );

// allocate it
lQuery = entityManager.createNativeQuery("update sequence set " + countColumnName + " = ? where " + nameColumnName + "=? and " + countColumnName + " = ?");
lQuery.setParameter(1, lAllocatedPK);
lQuery.setParameter(2, name);
lQuery.setParameter(3, lLastPK);
int lCnt = lQuery.executeUpdate();

// if we updated one record, we succeeded!
if (lCnt == 1) return lAllocatedPK; // the highest allocated key is the current value

// breeve pause (incremental)
ThreadUtil.sleep(lAttempt * 100);
}

// failed
throw new PersistenceException("Could not allocate a new value from sequence for " + name);
}
Re: manually allocate a @GeneratedValue [message #488382 is a reply to message #488350] Mon, 28 September 2009 13:44 Go to previous message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

There is an API getNextSequenceNumberValue(Class) on the EclipseLink Session interface which you can get from your EntityManager (cast to JpaEntityManager.getActiveSession()).


James : Wiki : Book : Blog : Twitter
Previous Topic:release plans
Next Topic:createEntityManagerFactory() returns null in RichClient application
Goto Forum:
  


Current Time: Thu Dec 18 00:46:54 GMT 2014

Powered by FUDForum. Page generated in 0.11223 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software