How to add a check to limit the number of rows created

I have a Grails domain class. I would like to add a check so that when the application is running in the TEST environment, the domain class cannot have more than 100 entries.

I cannot find a better way to add this type of check. I am on Grails 2.5.3.

This is what I still have.

class MyDomain {

String test

static constraints = {
   test blank: false, nullable: false
   id blank: false, validator: {value, command -> 
      if (Environment.current == Environment.TEST) {
          //do validation for not allowing more than 100 records
      }
   }
}

How to add this check?

+4
source share
2 answers

Single Domain Solution

What @Joshua answered is fine, but there are several other ways. One of them:

class MyDomain {

    String test

    void beforeInsert() {
        if (Environment.current == Environment.TEST) {
            MyDomain.withNewSession {
                if (MyDomain.count() == 100) {
                    throw new Exception("Not allowing more than 100 records")
                }
            }
        }
    }

    static constraints = {
        test blank: false
    }
}

Also, pay attention to two things:

  • blank: false id , , blank
  • nullable: false , nullable false

TL; DR

, , . :

Java src/groovy:

import java.lang.annotation.Documented
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Documented
@Target([ElementType.TYPE, ElementType.FIELD])
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitRowsFoo {

    int value() default 100
}

Groovy:

import grails.util.Environment
import org.grails.datastore.mapping.engine.event.PreInsertEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener

class PreInsertEventListener extends AbstractPersistenceEventListener {

    PreUpdateEventListener(final Datastore datastore) {
        super(datastore)
    }

    @Override
    protected void onPersistenceEvent(AbstractPersistenceEvent event) {
        // Instance of domain which is being created
        Object domainInstance = event.entityObject

        if (Environment.current == Environment.TEST) {
            if (domainInstance.class.isAnnotationPresent(LimitRowsFoo.class)) {
                // Just using any domain reference here
                MyDomain.withNewTransaction {
                    int maxRows = domainInstance.class.getAnnotation(LimitRowsFoo.class).value()
                    if (domainInstance.class.count() == maxRows) {
                        event.cancel()
                    }
                }
            }
        }
    }

    @Override
    boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        // Only allow PreInsert event to be listened
        eventType.name == PreInsertEvent.class.name
    }
}

Bootstrap.groovy:

application.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
        applicationContext.addApplicationListener new PreInsertEventListener(datastore)
    }

, , , , :

@LimitRowsFoo
class MyDomain {

    String test

    static constraints = {
        test blank: false
    }
}

@LimitRowsFoo(value = 200)   // to limit records to 200
class MyAnotherDomain {

    String name
}
+2

- ?

class MyDomain {

String test

static constraints = {
   test blank: false, nullable: false
   id blank: false, validator: {value, command -> 
      if (Environment.current == Environment.TEST) {
          //do validation for not allowing more than 100 records
          if (MyDomain.count() > 100) return ['too.many.records']
      }
   }
}
+2

Source: https://habr.com/ru/post/1665140/


All Articles