Abstract domain classes in GORM: how to deal with static GORM methods

grails, grails-orm, groovy

Solution

As in Java, the answer is likely to involve passing a `Class` object to the `AbstractParser` constructor.

public abstract class AbstractParser<T extends Entity> {

    protected Class<T> entityClass

    protected AbstractParser(Class<T> entityClass) {
        this.entityClass = entityClass
    }

    protected void parseAndSavePages(){

        //Do some parsing
        ...

        // Groovy treats instance method calls on a Class object as calls
        // to static methods of the corresponding class
        entityClass.withTransaction {
            if(entityClass.findEntityById(entity.id)){
                println "Already exists!";
            } else {
                entity.save(failOnError: true);
            }
        }
    }
}

class PersonParser extends AbstractParser<Person> {
    public PersonParser() {
        super(Person)
    }
}

Problem

Currently struggling with this. I was hoping to be able to use an abstract domain class to enable me to use some generic code to do some commonly performed operations. My problem is that a lot of the GORM operations are static methods on the domain class, this makes it difficult. Was wondering if there were any non-static equivalents of these methods, e.g. "withTransaction" "findById" etc which I could use. Or if there is any "groovy magic" that I could use? BTW, am using GORM outside of grails, so I don't think I have access to the "static transactional=true" service setting. Any help would be appreciated. abstract domain class: ``` @Entity public abstract class Entity<K> { public abstract String toNiceString(); public K id; public K getId(){ return id; } public void setId(final K id){ this.id = id; } } ``` and an example concrete class: ``` @Entity @EqualsAndHashCode class Person extends Entity<String> { String name String summary LocalDate birthDate LocalDate deathDate String occupations ... } ``` and some generic code whereby I was hoping to be able to reuse across some domain objects, but of course the T.xxxx() static methods won't work. ``` public abstract class AbstractParser<T extends Entity> { protected void parseAndSavePages(){ //Do some parsing ... T.withTransaction { if(T.findEntityById(entity.id)){ println "Already exists!"; } else { entity.save(failOnError: true); } } } } ```

Original source