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 = {
    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 = {
        familyName( )
        welcome( widget:'textarea' )
        ourFarm( widget:'textarea' )
        howMuchDoWeGetPaid( widget:'textarea' )


    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.counter = ric.counter + 1
            return ric.counter
        } else {
            return -1 


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 1.3.7, PostgreSql 8.4

Would there be a better way to do this? What potential problems am I overlooking?

  • \$\begingroup\$ Can you not simply declare the column in the db as auto increment? \$\endgroup\$ – konijn Jan 30 '14 at 23:43
  • \$\begingroup\$ Normally yes. I don't remember why exactly we opted not to do that though. I think we had to have it BEFORE persisting the details of the roast. It was not an ordinary ID column. \$\endgroup\$ – vector Jan 31 '14 at 12:02

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.

  • \$\begingroup\$ No, I don't think so, good point. \$\endgroup\$ – vector Feb 5 '14 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.