Search code examples
javaintegration-testingspring-roo

Customization of Spring Roo DataOnDemand getNewTransientObject method?


In our integration test for a Spring Roo managed entity, we're running into a problem in using AspectJ mix-in style interfaces which introduce not only methods with default implementations, but which also add an attribute annotated with JSR 303 validation rules. The problem is that the Spring Roo DataOnDemand logic does not see these fields and thus does not account for them in the getNewTransientObject() method.

For example, the following (simplistic) interface adds a "key" field to every entity that implements the "Keyed" interface:

import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public interface Keyed {

    public String getKey();

    public void setKey(String key);

    /**
     * AspectJ MixIn for any class which implements the interface. Provides a
     * default implementation using AspectJ. This is the style shown in
     * Manning's AspectJ in Action (2nd edition) for providing a default
     * implementation interface.
     * 
     * @author tgh
     */
    static aspect Impl {

        @NotNull
        @Column(name = "key", unique = true)
        @Size(min = 8, max = 12)
        private String Keyed.key;

        public void Keyed.setKey(String key) {
            this.key = key;
        }

        public String Keyed.getKey() {
            return this.key;
        }
    }
}


That's actually a solved problem for us. What we've done is to push-in the getNewTransientObject() method from the Spring Roo created AspectJ ITD (.aj) file and then made sure that the attribute gets set with an acceptable value. In our DataOnDemand.java file for the test class, we have the following fragment.

public KeyedExampleA getNewTransientKeyedExampleA(int index) {
    KeyedExampleA obj = new KeyedExampleA();
    setDescription(obj, index);
    setListPrice(obj, index);
    setName(obj, index);

    // Deal with mix-in variables that Roo doesn't know about
    obj.setKey("KEY_" + index);

    return obj;
}

What makes me uncomfortable about the above is that we're not creating a setKey(obj, index) method in the DataOnDemand.java file and using the same style as what Spring Roo generated for the getNewTransientKeyedObject(int) method.

Is it worth bothering to create the setKey(obj,index) method for such a trivial case, or should we just go with what we have of doing obj.setKey(value) inside the getNewTransientObject() method?

From looking at the Spring Roo created .aj files, I can't see that it makes much difference because there's nothing that calls setField(obj,index) other then the getNewTransientObject() method. And since Spring Roo isn't figuring out that we have mix-in introduced attributes, it probably won't ever care in the future either.


Solution

  • I would write the setKey() method just for consistency. But you are not causing any problems by not doing this.