HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Generating a sequential number for app-wide use

Submitted by: @import:stackexchange-codereview··
0
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:

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" }

} // Family


Service 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.