Wandering around JavaOne last week gave me a chance to think more about what Arid POJOs offers. I eventually came up with the term customizable convention over configuration or C2oC. Arid POJOs let's you define important conventions for your project's components. The previous examples showed how Arid POJOs can generate Spring bean definitions for services and DAOs identified by naming conventions, annotations or a combination of both. Craig Walls, author of Spring in Action, also had a nice write up in his blog . By establishing a set of conventions, you can significantly reduce the amount of metadata that you need to write to configure a POJO application.
One of the comments on the blog entry prompted me to take extend Arid POJOs in an interesting direction:
'Tyler Nelson' posted this on Thu 3 May 2007, 7:40 am
I added two new features to Arid POJOs. The first was a generic DAO capability with Grails GORM/Active Record-style dynamic finders. You write the interface for the DAO and Arid POJOs creates a proxy that implement some or all of the methods. I also extended <arid:define-beans> to scan a package hierarchy and for each type (class or interface) that it finds define a child bean that takes the original type as a constructor argument. This mechanism is used to define the Spring beans for the DAOs.
Let's first look at the Generic DAO feature.
There is an interface that defines some standard methods:
public interface GenericDao<T, U extends Serializable> {
public void add(T object);
public T findById(U pk);
public T findReferenceById(U pk);
public T findRequiredById(U pk);
public T merge(T object);
...
}
Each entity has it's own DAO interface that extends GenericDao e.g:
public interface AccountRepository extends GenericDao<Account, Integer> {
Account findByAccountId(String accountId);
List<Account> findByBalanceGreaterThan(double lower);
List<Account> findByBalanceBetween(double lo, double hi);
}
You could, of course, write your own implementations of each of these interfaces but most methods are pretty cookie cutter. Consequently, I decided to implemented something similar to Grails GORM and use a proxy-based mechanism to generate the implementations dynamically. Here is the definition of the accountRepository Spring bean:
<bean name="accountRepository"
class="net.chrisrichardson.arid.dao.hibernate.GenericDAOFactoryBean">
<property name="sessionFactory" ref="sessionFactory"/>
<constructor-arg value="net.chrisrichardson.arid.dao.AccountRepository"/>
</bean>
GenericDAOFactoryBean creates a proxy that implements the AccountRepository interface. When one of the custom findBy* methods is invoked, the proxy executes either (a) a named query with that name or (b) parses the method names and constructs a Hibernate Criteria query. If you need some handcoded DAO methods then you can define an abstract class that implements GenericDao and tell GenericDAOFactoryBean to generate a proxy that subclasses it and implements the abstract methods.
So where does Arid POJOs fit into this? With my latest change you can use Arid POJOs to generate the Spring bean definitions for the DAOs. Here is an example:
<bean name="parentGenericDaoFactoryBean" abstract="true"This example searches the net.chrisrichardson.arid.dao package for subtypes (interfaces and classes) of GenericDAO. For each type (e.g. AccountRepository) it then creates a bean definition that looks something like this:
<bean name="accountRepository"
parent="parentGenericDaoFactoryBean">
<constructor-arg value="net.chrisrichardson.arid.dao.AccountRepository"/>
</bean>
InterfaceAndAbstractClassPackageScanner finds classes and interfaces and ChildWithConstructorArgBeanGenerator generates the bean definition.
The combination of a Generic Dao mechanism with the ability to generate the Spring bean definitions can significantly simplify the amount of Java code and XML required to implement an application's DAO components. Moreover, the ability to search for types and generate child bean definitions could be used in other parts of the application.
Like it? Hate it? Please send me your feedback.
I like it very much, it's elegant, I think Arid framework could be
fantastic for expert developers, bennigers can be confused with interface
that's works without implementation.
I agree with dahernan. The idea is fantastic for developers who have at
least 2 years of experience with Spring.
Interesting that Ruby on Rails doesn't seem to think you need to be an
expert to call conveniently named methods. Is this a case of leaky
abstraction, or would the right presentation/tutorial make all this easy
for beginners, too? Or is our viewpoint just sometimes skewed in the Java
land of excessive code?