3

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.

5
  • I'm not sure what you are asking here. Are you asking whether it is ok to push in and modify the spring roo generated aspectJ files?
    – Chris Snow
    Commented Nov 11, 2012 at 8:31
  • 1
    It's more of a style question. Should we bother to create the setKey(obj,index) methods at all after doing the push-in? Or is there a better way to deal with the issue of Spring Roo not properly creating the getNewTransientObject() method?
    – tgharold
    Commented Nov 11, 2012 at 11:43
  • 1
    I would have done the same as you have done. IMHO, I don't think future Roo versions will ever get to know about custom AspectJ code that you have done.
    – Chris Snow
    Commented Nov 11, 2012 at 16:38
  • 1
    Where it does cause problem is that during the development phase, it becomes one more method that has to be manually updated every time you add another regular attribute to the class. I'm very tempted to write a second Aspect which advises getNewTransientObject() methods and sets the fields to a testable value, without having to push-in getNewTransientObject(). That way I could let Spring Roo manage the method, but my mixins would then require less work.
    – tgharold
    Commented Nov 12, 2012 at 14:39
  • The solution that I ultimately ended up using was to write that aspect as follows: stackoverflow.com/questions/13370167/…
    – tgharold
    Commented Nov 14, 2012 at 2:37

1 Answer 1

1

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

1
  • Yeah, I don't think there's a right or wrong to it. Creating an aspect to advise the DataOnDemand class made it even less of an issue because we could let Roo still build its own getNewTransientObject() method, but then advise it to set those additional members with suitable values. As shown at: stackoverflow.com/questions/13370167/…
    – tgharold
    Commented Nov 16, 2012 at 4:55

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