UTF-8 encoded binary brain

Posts tagged ‘Active Record’

Spring Roo and Active Record

Roo Screen Shot

Roo Screen Shot

I love Spring Roo! It makes everything so simple, especially when starting a new project, that I tend to forget how rainy and unproductive were the old days of Java programming. Now it’s like the spring has actually arrived after the winter of loads of XML files, procedural service-oriented coding and redundant classes and interfaces.

DAO, Repository and the Like

It’s so cool having tiers and layers. That if you’re an onion! But if you’re a software project what you mostly need is objects, not layers, because this is actually procedural programming in disguise.

There’s a famous book by Eric Evans that teaches how to get back to the roots and use the power of object oriented programming, I really love it. Problem is the book is pretty old and really hard to adapt to the kind of coding we’re doing nowadays. Using JPA/Hibernate is of a real help, but I needed Roo to teach me the courage to adopt the Domain Driven Development completely rather that just partially.

I always wondered how I would inject the Repository into the Entity in order to achieve that independence of the domain object, that standaloneness. It just did’t sound right to me. And a couple of years ago when I started looking at Ruby on Rails I realized how much simpler things can really be. Enter Active Record, farewell DAO/Repository/EAO/etc.

Roo Generates Active Record Style Entities

Spring Roo, among other cool things, can reverse engineer a database schema and turn it into a bunch of very useful and selfmaintaining entities. There’s only a simple command:

database reverse engineer --schema MYSCHEMA

And the magic starts happening. Roo scans MYSCHEMA and generates the entities. The interesting thing is how they are generated – using the Active Record pattern.

In case you didn’t just know, Roo generates most of the code in .aj files (AspectJ) and maintains that part. As you update the .java files, Roo maintains the generated code. But for the sake of simplicity, I’ve assembled the example below into one listing.

Let’s imagine an entity called Account. Roo would generate something of the sort:


public class Account {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "uuid", columnDefinition = "VARCHAR", length = 128)
    private String uuid;
    @ManyToOne
    @JoinColumn(name = "registration_request", referencedColumnName = "uuid")

    private RegistrationRequest registrationRequest;
    @Column(name = "email", columnDefinition = "VARCHAR", length = 128)
    @NotNull
    private String email;
    @Column(name = "public_name", columnDefinition = "VARCHAR", length = 128)
    @NotNull
    private String publicName;
    ...
    @PersistenceContext
    transient EntityManager Account.entityManager;
    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.persist(this);
    }
    @Transactional
    public void remove() {
        if (this.entityManager == null) this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Account attached = Account.findAccount(this.uuid);
            this.entityManager.remove(attached);
        }
    }
    @Transactional
    public void flush() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.flush();
    }
    @Transactional
    public void clear() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.clear();
    }
    @Transactional
    public Account merge() {
        if (this.entityManager == null) this.entityManager = entityManager();
        Account merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }
    public static final EntityManager entityManager() {
        EntityManager em = new Account().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }
    public static long countAccounts() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Account o", Long.class).getSingleResult();
    }
    public static List findAllAccounts() {
        return entityManager().createQuery("SELECT o FROM Account o", Account.class).getResultList();
    }
    public static Account findAccount(String uuid) {
        if (uuid == null || uuid.length() == 0) return null;
        return entityManager().find(Account.class, uuid);
    }
    public static List findAccountEntries(int firstResult, int maxResults) {
        return entityManager().createQuery("SELECT o FROM Account o", Account.class).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
    }
}

Isn’t that beautiful?!

No More Incomplete DDD

For too long I have written incomplete DDD code where almost all the business code went into the model objects themselves while some of it crept into the so-called service classes. So, if an entity needed another entity to make some calculations, things had to go into the service because this guy could have Repositories injected to retrieve the entities required for the respective  calculation. This made the DDD incomplete, impractical as well as boring to code.

The Active Record pattern is fixing this by making it simple to write (if not to generate) and beautiful to use:

// disable an account
Account account = Account.findByWhatever(whatever);
account.disable();

or

// use the new keyword
// TODO even better, use a static factory or builder
Account account = new Account();
account.setEmail("my@email.com");
account.setPassword("secret");
account.persist();

Efficiency

I’ve always hated writing boilerplate code. The service classes were usually Spring Beans or EJB stateless sessions. They also called for an interface, not necessarily, but it is considered a good practice. OOP? To me the service class looked a lot like C code. No state at all, just some methods grouped in by functionality. It even had the header file – the allegedly good-practice interface.

Using Active Record and implementing a rich domain can replace a lot of boilerplate code and make everything more natural, object oriented and efficient.

Testing is Impossible Using Active Record

God, I hear that a lot. Is it just me or people like to repeat what the hear instead of thinking about it for a minute? There is this thing that was invented like in the Stone Age of Agile development – it’s called mocking. Nowadays with the advancing of technology, the invention of iPad 2 and the sending of a new rover to Mars, we can mock even the static methods.

To prove to you testing is possible, Roo even generates the (integration) tests. But I won’t paste the example here, I’ll let you try it instead. I works, you know!

Stay productive, efficient and employed!

Follow

Get every new post delivered to your Inbox.