Monday, June 05, 2006

Grails & EJB3 Entity beans

One of the features that I mentioned at JavaOne that got people all excited was Grails' support for EJB3 entity beans. Grails comes with it's own ORM solution built on-top of Hibernate called GORM, but because of this relationship with Hibernate Grails domain models can also be written in Java.

One way to do this is to use the EJB3 annotation support in Hibernate which will of course allow you to use all the power the API offers in terms of mapping onto legacy systems. Clearly this is all not that exciting so far, what is really exciting is that even though the EJB3 entities you've created are written in Java and mapped using Java persistence annotations you can still use all those fantastic dynamic finder/persitence methods to manipulate your domain model from a Grails controller or service class!

Some examples of these in action are listed below, Grails uses the properties of the domain class itself (combined with the wonderful Criteria API) to implement the finders:



def a = new Author(name:'Stephen King').save()
def b = new Book(author:a, title:'The Stand').save()

def results = Book.findAllByTitle("The Stand")

results = Book.findAllByTitleLike("Harry Pot%")
results = Book.findAllByReleaseDateBetween( firstDate, secondDate )
results = Book.findAllByReleaseDateGreaterThan( someDate )
results = Book.findAllByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )

// find by relationship
results = Book.findAllByAuthor( Author.findByName('Stephen King') )



This is one of the awesome features of Groovy's Meta Object Protocol (MOP), it allows you to add new methods, properties,constructors etc. to any existing Java class, it doesn't have to extend GroovyObject or have any knowledge of the Groovy runtime environment. Think of it as AOP without the byte code manipulation.

Taking this approach is quite appealling at it allows the blended development I mentioned in the talk. Mixing dynamic and static typing is the way to go in my opinion. The debate between these two is a bit of a red herring. This way you have all the power of static typing with its refactoring capability in IDEs, plus the ability to use a dyanmic framework like Grails as the view/controller layer in your web application.

You can also then re-use your domain model across tiers or from regular servlets or via a Swing interface very simply because it is still in Java. The main target for Grails has always been to create a framework with the essence of Rails, but taking Java integration to a new level. Features like this are exactly what is helping us achieve this very goal.

3 comments:

Anonymous said...

But if you refactor the static side, the dynamic side breaks. And "show references" won't tell the truth, either.

For a dynamic language to be appealing from this front, we need freely available tools that "just work" providing the same features as for static languages. Otherwise, the static-typing benefits still die off.

That may be a worthwhile trade off for some needs, but half static doesn't really work the same as all static.

Graeme Rocher said...

depends on your IDE, IntelliJ allows you to include text files that match to the refactoring. And in Groovy you can alias an imported class name like this:

import com.mycompany.MyClass as MC

MC.thisIsAStaticMethod()

Thus renaming the class would be picked up by the IDE.

Clearly though you make a good point as not all refactorings would work. However this is where Groovy as a language is an interesting proposition as it allows both static and dynamic typing hence refactoring tools could be made to work. All it involves is further development on the IDE support.

In addition to this web actions in Grails are very concise, and if you logic becomes complex we encourage use of a Service class (business layer). This of course all depends on the requirement, the point remains is that Grails can scale in terms of application complexity.

Anonymous said...

I think the one of the big benefits of Groovy is the fact that the integration with Java is seamless. This means you can leverage the dynamism of Groovy/Grails where it makes sense to do so while retaining the ability to develop large parts of your code base in tooled, statically typed pre-compiled Java.

For risk averse developers the best solution may be to use Groovy/Grails for the CRUD stuff but leave the rest of their app in plain old Java.