ALTERthought Blogs

25 July 2006

Java on Rails? Trails: What it is (and isn’t)

Much to-do has been made recently about Rails, and the productivity gains that are to be had from the infrastructure it provides. Listed among these gains comes a productivity boost that can be had from the embracing of a Domain Driven Development approach, whereby the developer concentrates on the Domain model and the framework (in this case Rails) provides some automagic plumbing an duct work on behalf of the programmer.

The Trails project is a rough analog to this approach (although the author seems to regret somewhat the ‘Trails’ moniker as it people naturally jump to the conclusion that it is a java version of Rails; which it is not.) This post describes my recent experimentation with the Trails framework, and my subsequent opinions on when/where/etc it might be appropriate.

Let me first start out with a disclaimer of sorts, around RoR. I have very little practical experience to date with Rails, let alone Ruby; and as such, I am not attempting to compare Trails to Rails. Also, this is not a tutorial on Trails…Several links off the Trails project homepage provide an excellent and easy to follow tutorials which will guide you thru the basics.

Trails in a Nutshell

Trails can be neatly summed up with a (slightly modified) quote directly from the project home page:

The trails project aims to make [web based] java enterprise application development radically simpler by allowing developers to focus on the domain model and having other portions dynamically generated.

Basically, you, the developer, provide:

The Trails framework in turn automagically provides just about everything else. Including :

So lets say you had an application that dealt with an inventory of Automobiles. You would first set up a trails project (using a provided ant task), and then define a basic POJO Domain Object:


@Entity
public class Car
{
private Integer id;
private String make;
private String year;
private String model;

@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId(){ return id; }

public void setId(Integer id) { this.id = id;}
public String getMake(){ return make;}
public void setMake(String make){ this.make = make;}
public String getModel(){ return model;}
public void setModel(String model){this.model = model;}
public String getYear(){ return year;}
public void setYear(String year){this.year = year;}
}

The only interesting thing in this class are the handful of annotations that indicate that we want this object to be persisted (@Entity) and we want an unique Object Id auto assigned. Basically we are using the JPA to indicate to Trails (and in this case Hibernate) what gets mapped to our database.

That’s all the code we write.

When compiled into a war and deployed into a servlet container (using the ant build script that Trails provides for you), we get this when we point a browser at http://localhost:8080/blog

Screenshot:1

Clicking around allows us to enter some new car data:

Screenshot:2

… which we can then list out here:

Screenshot:3

WOW. Pretty nifty. And not bad for about 5 minutes work. Less even.

OK. This is obviously a very simple/dumb application. Its straightforward and (generally) easy to add additional Domain relationships (OneToMany, ManyToMany,etc), automatic data validation, and UI customization with a bit more work (all of which is detailed in the links available from the Trails project home page)

The Pros & Practical Applications

The Cons

The Conclusion

Trails is cool. Very cool. And for certain types of applications it gets 2 thumbs up. Don’t let the listed cons keep you from exploring its value to you. That being said, it seems most valuable for quickly generating Administrative interfaces to existing applications, where the look and feel can be CRUDe (crude, get it?). Working the basic CRUD paradigm into an application with significant business logic seems daunting; and probably more work then solving the problem in a more ‘conventional’ J2EE approach.

Technorati Tags: , , ,

    del.icio.us

Comments are locked.

ryan says:

Can you expand upon what is meant by this, “Establishing relationships between Domain Objects requires JPA knowledge”?

don says:

I can try ;) The EJB3/JPA syntax uses Java5 annotations to establish the relationships between domain objects. So if want the above defined Car object to have a collection of Part objects (yeah I know its dumb), you might declare an attribute within the Car Object like so:
private Set parts = new HashSet();

..and then establish the One-Car-Has-Many-Parts relationship with an annotation on the accessor for the Parts:

@OneToMany
public Set getParts()

And if you want the Part objects in turn to know about the Car that collects them, you would have establish the ManyToOne relationship within the Part Class; as well as establish the mapping column to be used:
@OneToMany (mappedBy=”owningCar”)

…there are then a host of other adornments that can be layered on controlling cascading, lazy loading, etc. Basically, all the stuff that you have to know in order to use Hibernate directly, you need to know with the JPA. Once again, not really Trails problem, but still necessary.

ryan says:

Gotcha, so Trails doesn’t auto-wire relationships based on conventional column names (as Rails does) - it’s up to you to define them using JPA demarcations?

I wonder how difficult it would be to take it that step further and build in auto-sensing relationships…

Graeme Rocher says:

This is exactly what Grails does with GORM (http://grails.org/GORM). We built an ORM mapping strategy built on Hibernate that uses the convention in the classes instead of annotations/XML.

don says:

Ryan/Graeme,

Well with my disclaimer around my general lack of Rails experience in tact; you have it correct. Trails does not autowire relationships based on names. It does however create tables/columns/etc for you and there is a standard naming convention at play there… but it is more one associated with the JPA standards, less Trails.

I have been meaning to more fully investigate Groovy in general, and Grails in particular; so perhaps now is my excuse. Thanks for the tip.

-don

ryan says:

Don, I think I mis-spoke - Rails doesn’t auto-wire relationships per-se. You have to say something like:

has_many :parts

…similar to the annotation you would use in your examples. However, you don’t have to tell it what columns to use if you follow the convention (i.e. car_id column in the parts table) thereby avoiding the mappedBy=XXX annotation attribute in Java.