javaormactive-objects

How is @Implementation used?


Recently I discovered ActiveObejcts and I really like it. Right now I'm using the last version from Atlassian plugin, only the net.java.ao part for ORM. Compiles and runs fine. Sure, I have to do some performance tests, if it fits my requirements.

There exists the @Implementation annotation. How is that used? The javadocs are very brief.

Update

Solution:

public class M5 {

public static void main(String[] args) throws SQLException {

        EntityManager m = EntityManagerBuilder
                .url("jdbc:hsqldb:./db/db")
                .username("root")
                .password("")
                .c3po()
                .build();

        m.migrate(Employee.class);

        Employee p = m.create(Employee.class);
        p.setFirstName("Peter");
        p.setLastName("Mmm");
        System.err.println(p.getLastName()); // prints "ln: Mmm"
        p.save();
    }
}

public class Emp {
    private Employee employee;

    public Emp(Employee employee) {
        this.employee = employee;
    }

    public String getLastName() {
        return "ln: " + employee.getLastName();
    }
}

@Implementation(Emp.class)
interface Employee extends Entity {
    String getFirstName();
    void setFirstName(String name);
    String getLastName();
    void setLastName(String name);
}
}

Solution

  • Active Objects takes your interface and, via reflection through a complicated proxy translates your getters, setters and relations into SQL statements. If you want some of your own code in there to add or modify functionality of your AO interface, you can use @Implementation

    Example:

    AO interface:

    @Implementation(PersonImpl.class)
    public interface Person extends Entity {
    
      String getLastName();
      void setLastName(String name);
    
      String getFirstName();
      void setFirstName(String name);
    
      @Ignore
      String getName();
    }
    

    Implementation:

    public class PersonImpl {
    
      private final Person person; // this will be the original entity proxy
    
      public PersonImpl(Person person) {
        this.person = person;
      }
    
      // "Implement" ignored functions
      public String getName() {
        return String.format("%s %s", this.person.getFirstName(), this.person.getLastName()); 
      }
    
      // "Enhance" AO getters/setters
      public void setFirstName(String name) {
        this.person.setFirstName("Foobar");
      }
    }
    

    Note that AO accesses these implementation methods via reflection. They must match the names in the interface. This might lead to problems during refactorings, as method names might change and your compiler won't tell you that your corresponding impl method name hasn't.