Frequently Asked Questions
From time to time I get quizzed on the design choices that shaped JumpStart. Here's what I was thinking when I made them.
- Rapid development. Rapid debug.
- It is page-oriented, not action-oriented.
- The focus is on the app, not the plumbing.
- Config is minimal. We're free at last from XML hell!
- The feedback is so immediate that you feel very in control.
- It can read and write domain entities directly.
Why Ant and not Maven?
Some people love Maven, some people hate it. I like the intention of Maven but I'm very influenced by having seen it waste so many days of people's precious time.
In contrast, Ant can do the same stuff yet be really simple, transparent, and easy to modify. I wanted to explore that, so that's why JumpStart uses Ant. OK, so Ant doesn't do automatic dependency management, but is that really much of a loss? I'm not convinced that it is.
Maven has not been completely ignored, however. You'll notice that the Ant targets and classpaths are modelled directly on Maven's very sensible targets and classpaths. Even the project structure is modelled on Maven's conventions, because it's a structure that works well.
Why Session Beans?
I'm completely sold on the virtues of having a separate business layer. It imposes a discipline on the way you think about the problem. So why do the business layer with Java EE Session Beans? Because they are so simple to use, while giving you so much for free:
- Persistence (JPA)
- Transactioning (JTA)
- Remotability (RMI)
- Readiness for new interfaces (eg. remote desktop apps, web services, JMS requests, new web UIs)
- The focus is on the app, not the plumbing (just like Tapestry)!
- Config is minimal. We're free at last from XML hell (just like Tapestry)!
Session Beans are a type of Enterprise Bean, formerly known as EJBs. The slightly out-of-date, but excellent, book EJB 3 in Action can be downloaded for free from 4shared.com.
What about those annoying LazyInitializationExceptions?
Actually, I think LazyInitializationException is our friend. The practice used in JumpStart is to declare every relationship as lazy loading, then make good use of join fetch in the business layer queries wherever it makes sense. Sure, we could side-step the LazyInitializationExceptions altogether by using the open-session-in-view pattern, but that throws the door open to letting the "N+1 Selects" problem sneak in unnoticed. I prefer to have LazyInitializationException thrown, because it forces you to look hard at what the business layer is up to.
Some good reading: Avoiding ORM Performance Pitfalls. It's an old post but as relevant as ever.
Are the business services the same thing as DAOs?
No. The business service classes are simple users of the domain entities through JPA. They don't need to do much business logic, because with JPA it's fine to move business logic into the entities that understand it, ie. entities can now have real encapsulation with real business methods rather than being just a bag of getters and setters (see AnemicDomainModel - another old post but still as relevant as ever).
Where are the DAOs?
Why did the Data Access Object pattern ever exist? As I recall it had two purposes: to abstract away the data sources, and to hide the implementation of accessing the data. That is exactly what JPA (Java Persistence API, also known as EJB3 Persistence) does too. So I argue that JPA has taken the place of the DAO and there's no need for us to write our own. JumpStart uses JPA as its DAO.
Where are the DTOs?
There's still a place for Data Transfer Objects, but they're not needed as often as they used to be. That's because JPA lets us detach entities for use in the web layer. In my opinion the argument for hiding the domain model from the web layer has been well and truly lost in favour of pragmatism. An example of a DTO in JumpStart is UserSearchFields.
Is JumpStart dependent on Hibernate?
Yes, JumpStart is ever so slightly dependent on Hibernate. JumpStart has one brief reference to Hibernate - in BaseEntity - but the reference could be removed with a small loss of functionality.