databasegrailsgrails-ormdomain-object

Best way to design Domain with constant in grails


I have lots of domain classes in my project. Many of them has type column. For example: User table has userType column, Book table has bookType column. I often pass these types into GSP g:select source by calling BookType.list() method. But problem is if GSP contains lots of g:select then I have to execute lots of redundant query.

And another problem is when I create a new Domain instance, I have to get these constant types from DB by following way

Book book = new Book();
book.bookType = BookType.findByName(BookTypes.COMICS);

Here I also have the same problem, I have to execute redundant query. Is there any good design to do all these stuff without executing these redundant queries?


Solution

  • If the types are not very volitile, I assume that is the case because I can see you defined an enum for type. Try using enum, totally -- I mean, don't bother with the database table at all to back that up. For example,

    enum SomeType {
    
        TYPE1(1, "Type 1"),
        TYPE2(2, "Type 2"),
        TYPE3(3, "Type 3")
    
        final int id
        final String value
    
        private SomeType(int id, String value) {
            this.id = id
            this.value = value
        }
    
        // Might be needed for <g:select> tags, I'm not very sure
        int getKey() { id }
    
        static SomeType byId(int id) {
            values().find { it.id == id }
        }
    }
    

    Then, in your domain, do something like,

    class SomeDomain {
    
        static constraints = {
            ...
            type nullable: false
            ...
        }
    
        ...
        SomeType type
    }
    

    Then, you can simply do something like this,

    SomeDomain book = new SomeDomain(..., type: SomeType.TYPE1, ...);