patternMinor
Generating a sequential number for app-wide use
Viewed 0 times
numberappwidesequentialgeneratingforuse
Problem
I have to generate a sequential number for groovy-grails app wide use and came up with the following. However, is there a better way to do this?
Domain classes:
This one has no views or controller associated with it. It's purely for db interaction in a service class.
Service class for dealing with the number generation:
Controller:
Here I'm just sending the object all pre-populated:
Environment: Grails
Domain classes:
class RoastIdCounter {
int counter =0
static constraints = {
}
}This one has no views or controller associated with it. It's purely for db interaction in a service class.
class RoastId {
Family family
Integer nextId
long timeCreated = new Date().time
static constraints = {
family()
nextId()
}
static belongsTo = [ Family ]
}
class Family extends {
String farmId;
String welcome;
String familyName;
String ourFarm;
String howMuchDoWeGetPaid;
SortedSet pictureAlbums;
SortedSet pictures;
Integer pictureAlbumsCount = 0;
Integer picturesCount = 0;
Date dateCreated = new Date()
Date lastUpdated = new Date()
static hasMany = [ roastIds : RoastId, pictureAlbums : PictureAlbum, pictures : Picture ]
static constraints = {
farmId()
familyName( )
welcome( widget:'textarea' )
ourFarm( widget:'textarea' )
howMuchDoWeGetPaid( widget:'textarea' )
dateCreated()
lastUpdated()
}
String toString() { "$farmId - $familyName" }
} // FamilyService class for dealing with the number generation:
class RoastIdCounterService {
static transactional = true
def getNextRoastId() {
def ric = RoastIdCounter.list()[-1]
if( ric != null ){
ric.lock()
ric.counter = ric.counter + 1
ric.save()
return ric.counter
} else {
return -1
}
}
}Controller:
Here I'm just sending the object all pre-populated:
def create = {
def roastIdInstance = new RoastId()
roastIdInstance.properties = params
roastIdInstance.nextId = roastIdCounterService.getNextRoastId()
return [roastIdInstance: roastIdInstance]
}Environment: Grails
Solution
Have you considered using an AtomicLong instead of the RoastIdCounterService? You can then call AtomicLong.incrementAndGet() to get the next value. The atomic long will take care of the locking required for safe concurrent access.
Context
StackExchange Code Review Q#958, answer score: 3
Revisions (0)
No revisions yet.