- Andrew Kos
- Bill Burlein
- Bryan Williams
- Christian Vozar
- Jeff Brown
- John Kraus
- Joseph Mak
- Mark Daugherty
- Matt Van Bergen
- Melissa Geoffrion
- Michael Kang
- Michael Chan
- Michael Hodgdon
- Mike Motherway
- Molly McDaniel
- Nadia Maciulis
- Pat McLoughlin
- Paul Michelotti
- Puru Hemnani
- Rohit Srinath
- Ryan Lunka
- Tom Kelly
An Honest Look at Seam – Part 2: The Conversation
Wednesday, March 24, 2010
This is the second part in a series of posts about the Seam Framework
The next part of Seam I want to look at is the Conversation. A conversation in Seam is one of the new contexts that seam brings to the table. It sits in between the Servlet Request and Session in terms of it’s life in the application. The goal of the conversation context is to fill in the gap scoping objects across a logical set of requests that represent a real user case without having to juggle everything in the session. It also allows you to have multiple “workspaces” of your application on different browser tabs, as each tab can have it’s own set of conversations.
Now, what do you think belongs in this conversation context? An easy win here are Stateful Session Beans. The references to these are a no-brainer for the conversation context as they represent a conversation with the EJB container. We can also put business objects that we are building up as part of a wizard into a conversation. In fact, that is exactly where I want to go, proposing that those objects should be your JPA entities. Here’s why. When you use Hibernate as the persistence mechanism or the JPA provider with Seam, you get some extra goodies for tying the persistence context to the conversation. This feature is best understood in contrast to the way most of us have to work in other frameworks.
In most any other web framework, you would have to look up your JPA entity on the first step of your wizard, and either pass it as a detached entity through the wizard, making a JPA merge call at the end to persist the change, or you can manage and merge the changes yourself. Either way, merges are messy, and either blind to data clobbering or complex to code. Also, the fact that your JPA entity is detached means you can’t traverse the object graph without either getting lazy load exceptions (we all love those) and/or having to re-lookup the entity for each page.
There are two things that Seam does to address this problem. The first is that it binds the entity manager to the conversation, and keeps it open for the life of conversation, across multiple requests and multiple transactions. (Seam still runs with a transaction per request model, but you will see how the conversation works with that by the end of the post). This means that you can keep references to your JPA entities across requests and they don’t get detached. This reduces traffic to the database because you aren’t looking up the data in the database over and over again with each request. You also don’t have to resort to the “Open Session in View” pattern in order to avoid lazy load issues in your view layer.
The second thing Seam does has to do with a special feature in Hibernate. Hibernate implements a additional flush mode for the entity manager beyond JPA’s AUTO and COMMIT, called MANUAL. What it does is tell the entity manager to not flush changes to the database until it is told to, even across transactions. Seam will enable (when you ask it to) the MANUAL flush mode of Hibernate on your conversation scoped entity manager, which means you can modify your entity on the first page of the wizard, carry those changes through, and not have them flush (and thus commit) until the conversation is ended. This is significant because if the conversation never completes, the changes the user made during the wizard are “rolled back” when Seam cleans up the abandoned conversation (which it does for you without you having to worry about it). You get this rollback without having to detach your entities or worry about the data from the wizard ending up in an inconsistent state.
Now, the one caveat to this is that you must use Hibernate to get the Manual flush piece. The other pieces (including the conversation scoped entity manager) are available no matter what JPA provider you use. With that in mind, write to the JPA expert group and tell them you want manual flush to get into the next revision of the spec!
In the next part, we will take a step back from the features and address a question that I have gotten a lot about Seam. “Seam seems to be really complex and big. How do I go about learning it?”
Previous Posts in the series
Part 1: How Seam Builds on Spring
- Invisible requirements within Business requirements
- Building a better Options Predicate
- Extensionless URLs with Adobe Experience Manager
- The Life of a Tester in Adobe CQ World!
- Limitations of the CQ Parsys Model and the Implementation of a Nested Paragraph System
- Using Apache FOP to generate a PDF document based on a form submission data
- Configuring SAML in AEM 5.6
- Why You Should Get the WCM Experts Involved Early