Saturday, August 16, 2008

How to construct immutable objects using reflection

John O'Hanley argues that Javabeans should not be used with database frameworks. The reason various ORM frameworks use Javabeans is because they need to be able to construct objects using reflection. Javabeans provided this capability, whereas constructors were hard to introspect (at least as of Java 1.4) because the compiler saves only the types of method arguments, and not their names. The need to reflectively set properties by name is a legitimate one. Javabeans, by virtue of their extreme mutability, are certainly a problematic approach. But rather than discarding Javabeans and ORM entirely, John, you should propose a solution for those who want ORM. Then you will be taken more seriously. Perhaps Java 5 annotations finally give us enough capability to construct immutable objects reflectively. A constructor could be given an annotation that tells the ORM framework how its arguments map to entity fields.


John said...

One option is the web4j tool that I built ( I didn't emphasize web4j in the article, because I thought it was inappropriate.

The web4j data layer works fine, and it uses immutables.

It's originality centers on using an ordering convention instead of naming convention. This convention eliminates the need for explicit mapping.

More explicitly, the order of columns in a ResultSet (not a table) are mapped in order to the arguments of a domain object's constructor...

- John

Jeoff Wilks said...

Web4J specifically disclaims any ORM support, which is why I linked to it above (and ORM).

It sounds like you have a record-mapping capability similar to Spring's JDBC Template. In saying it isn't ORM, you acknowledge its limitations. I like your constructor-based approach; however I think name-based mapping adds an important validity check. Object graph management too is a valuable feature.

A constructor annotation could easily be added to Hibernate... this would allow you to preserve the desired level of mutability without sacrificing all the benefits of a comprehensive ORM toolkit.