Nov 28
Bleeding Edge Transactional Wicket Web Applications with Warp and Guice
One of the reasons that I think Spring has become so popular in web applications is that there simply hasn’t been another widespread web application stack that (1) is free, (2) is not Java EE, and (3) doesn’t involve JSF.
Wicket (which I’ve written about in passing before) is a great component-based web framework that integrates nicely with Spring (and therefore Hibernate and/or JPA), making it a great choice for a web stack that looks like this:
- Wicket [web tier]
- Spring [transactional / business tier]
- Hibernate [data access tier]
But what other choice is there for a transactional / business layer if you (for whatever reason) don’t want to use Spring?
Fortunately, Dhanji Prasanna has been hard at work on a transactional framework for Guice called warp-persist.
Technically, warp-persist is part of Dhanji’s Warp web application framework, but it can be easily used on its own in a Wicket/Guice stack.
Like Guice, Warp has some fine documentation to get you started, but I’ll try to provide some help here, as I’ve gone through the effort to “port” a Wicket/Spring/Hibernate application to use this framework (for development purposes only!).
This is what our web stack will look like:
- Wicket 1.3 [web tier]
- Guice [dependency management]
- Warp-persist [transactional management]
- Hibernate [data access tier]
Wicket 1.3 is required because it is the first version of Wicket to offer built-in Guice support. Although it is possible to roll your own Guice support with Wicket 1.2, since the framework has it built-in in 1.3, and 1.3 has hit release candidate phase (finally!), you might as well make the migration to Wicket 1.3.
I’ll assume that you know how to get Wicket and Hibernate up and running, so we’ll go through the steps required to get warp-persist and Guice integrated with Wicket and Hibernate. Here’s the rough outline:
- Get a copy of warp-persist
- Set up the warp-persist servlet filter
- Integrate warp-persist with the Guice framework
- Integrate Hibernate with warp-persist (via Guice)
- Service layer and data access layer changes
Get a copy of warp-persist
Check out the trunk of the warp-persist code from Google Code’s Subversion repository using the following URL: http://warp-persist.googlecode.com/svn/trunk/warp-persist
Set up the warp-persist servlet filter
We’ll need to add the warp-persist equivalent of the Spring OpenSessionInView Filter to our web.xml file. This will ensure that a Hibernate session is available (via warp-persist) in layers of our application below the web layer.
Add this after the Wicket servlet filter (which was added in 1.3):
<filter> <filter-name>MyWicketApplication</filter-name> <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> <init-param> <param-name>applicationClassName</param-name> <param-value>com.mularien.MyApplication</param-value> </init-param> <init-param> <param-name>filterMappingUrlPattern</param-name> <param-value>/*</param-value> </init-param> </filter> <!-- Warp Filter --> <filter> <filter-name>warpSessionFilter</filter-name> <filter-class>com.wideplay.warp.hibernate.SessionPerRequestFilter</filter-class> </filter> <filter-mapping> <filter-name>warpSessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Warp Filter -->
Integrate warp-persist with the Guice framework
Next, we’ll set up the Guice injector. We’ll pass 2 Modules to the constructor – the first is the one that warp-persist creates for us, and the second is the Module used for our web application. This is done in the init method of our Wicket application:
injector = Guice.createInjector(PersistenceService.usingHibernate() .across(UnitOfWork.REQUEST).transactedWith( TransactionStrategy.LOCAL).buildModule(), new MyApplicationModule());
The warp-persist documentation describes in more detail exactly what all of these bits do – basically, we are setting things up with a locally-managed transaction strategy (JTA users will do this slightly differently) and a request-scoped unit of work.
We need to make the Module generated by warp-persist the first Module passed to Guice. This is because we need to add some code to our application’s module (MyApplicationModule) to initialize Hibernate, and this requires the warp-persist stuff to happen first.
Integrate warp-persist with the Guice framework
Now, we’ll add some code to our Module to set up the Hibernate configuration. In my case, I was using annotated classes, so I initialize my configuration with the org.hibernate.cfg.AnnotationConfiguration class:
final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration(); annotationConfiguration .addAnnotatedClass(com.mularien.Employee.class);
… etc. Continue setting up the Configuration as you would using the normal Hibernate API (which you may be a little rusty on after years of Spring use like me).
One important bit is to make sure to tell Hibernate to use locally-managed transactions (remember, we aren’t using JTA in this proof-of-concept). To do this, add the Hibernate property as directed by the warp-persist documentation:
annotationConfiguration.setProperty( "hibernate.current_session_context_class", "managed");
Finally, wire up the Configuration using Guice:
bind(Configuration.class).toInstance(annotationConfiguration);
Now we have Guice wiring up our warp-persist hooks to Hibernate.
We have to start the warp-persist PersistenceService. A good place to do this is in your Wicket Application’s init method, after you set up the Guice injector (as shown above). Unfortunately here we run into the only strange part of the whole setup. You need to do this:
persistenceService.start();
… in order to get the warp-persist bits started. PersistenceService is provided only by Guice injection. The start method will (for Hibernate) actually do the work of creating the Hibernate SessionFactory based on the Configuration binding we set up in our application’s module – so if you have any Hibernate errors in your configuration, they will be thrown at this point.
In order to get a reference to warp-persist’s PersistenceService, you’ll have to interrogate the Guice injector directly:
persistenceService = injector.getInstance(PersistenceService.class);
… or set it up as a dependency with @Inject and have Guice inject it. The issue with this is that the Wicket-Guice integration module requires the GuiceComponentInjector be set up as a component instantiation listener. When your application is started, you’re already past the point for automatic injection. If you want to add a reference to Warp’s PersistenceService in your Wicket application, you can force Guice to inject your application as follows:
injector.injectMembers(this);
Now, once your Wicket application starts, warp-persist should correctly inject its various bits via Guice, and your Hibernate configuration should be set up and initialized.
Just a couple more steps before you’re finished up!
Service layer and data access layer changes
You’ll need to remember to add @Transactional tags to your business/service layer as appropriate (I won’t cover this here, as the documentation provided by warp-persist is much more thorough than I could be).
The final step is to add a [Hibernate] Session Provider (or, Provider
@Inject
Provider<Session> session;… where Session is a org.hibernate.Session. In order to get a reference to the session in your data access methods, you’ll do this: session.get(), followed by a Hibernate API call (createQuery(), get(), etc.).
At this point, if you’re like me and have used Spring extensively, you’ll start missing some of the convenience methods built into the Spring ORM abstraction layer. Warp-persist doesn’t [yet] provide some of the nice wrapping and exception conversion provided by Spring ORM – you’re dealing directly with the raw Hibernate APIs. While not bad, if you’ve been stuck in Spring-land for some number of years, it’s definitely an adjustment.
Parting Words
This completes the last and final step to get warp-persist and Guice integrated into your Wicket / Hibernate application.
As a proof-of-concept, I think it’s fascinating that warp-persist and Guice have provided a plausible stack to replace common uses of Spring as middleware in web applications. Thoughtful readers will note that there’s a lot more that Spring does which isn’t covered here (security via Acegi being most noteworthy).
The other important note is that Warp hasn’t reached an official release status yet. In writing this article, I corresponded via email with Dhanji, who said that users should consider the API “officially Beta”, and said that he is planning on working towards a release candidate (and a formal release process) soon.
In the meantime, in order to play with it and follow the examples here, you’ll have to check out directly from the Warp subversion repository. Based on this, and until a release candidate appears, I’d hesitate to recommend warp-persist for anything beyond investigative development and something to keep an eye on. Dhanji (the lead / only developer) is definitely committed to seeing the project flourish, and has demonstrated a good working relationship with the Guice team. Hopefully the Warp project gets some interested developers to pitch in!
Enjoy – please post comments/feedback if you have any!
Further Reading
Uwe Schaefer has uncovered a potential pitfall when using Guice with Wicket, and he’s kindly documented it on the Wicket Wiki.


November 29th, 2007 at 12:38 am
Thanks for post!
April 19th, 2008 at 1:06 pm
[...] best place to start with integrating these components would be Peter Mularien’s blog post on integrating warp-persist and wicket (but not wicket-guice). Peter’s post, while good, does [...]
October 23rd, 2008 at 11:00 pm
[...] http://www.mularien.com/blog/2007/11/28/bleeding-edge-transactional-wicket-web-applications-with-war... [...]
October 12th, 2009 at 10:39 pm
[...] from the current 1.0 releases of Guice and Warp-persist. And really, most of what I did I got from blog 1 and blog 2. The current Warp-persist 2.0 docs are a [...]