Monday, June 6, 2011

Spring, JPA, Java EE, JBoss: deployment strategies

Last week I made a comment on Michał's post - which I strongly recommend, by the way - where I alluded to the possibility of using an entity manager factory created by the application server instead of using the local JPA entity manager factory beans. Since I have been asked to provide a more detailed description, I will do this in a separate post, as doing that within the comment space is rather difficult, especially when providing code samples. The context of this discussion is the JBoss Application Server, but most of the considerations apply for other Java EE-compliant application servers as well.

Automatic creation of entity manager factories in JBoss

When using Spring and JPA in a servlet container, developers can create an EntityManagerFactory by using a LocalEntityManagerFactoryBean or a LocalContainerEntityManagerFactoryBean. In such an environment, it is pretty much the only option available. In JBoss, they can still do that, or they can choose to rely on the application server to create such an EntityManagerFactory for them.

Typical JPA applications will contain a META-INF/persistence.xml file which contains the persistence unit definition. JBoss, as a full-fledged Java EE application server, will deploy the persistence unit (and therefore create a EntityManagerFactory), whenever such a file is present in the deployment. So, unless special steps are taken to prevent that from happening (more about that below), the EntityManagerFactory will come into existence automatically. As a side note, you are required to use JTA in this case, as Java EE does not support the deployment of persistence units with the RESOURCE_LOCAL setting. If you are worried about how JTA will affect your performance however, please note that JBoss will optimize transaction management in single-resource scenarios, so any overhead is hardly significant.

So, once you provide a META-INF/persistence.xml file with your application, there is no actual need to create a new EntityManagerFactory in Spring, but you still need to create a reference to the container-managed entity manager factory which you can further inject that into your DAOs, and you can do that through a JNDI lookup. In order to do so, you need to register your EntityManagerFactory in JNDI. Web applications can do this by adding this to their web.xml file.

Adding a persistence unit reference to web.xml


Once this is done, the entity manager bean definition can be:

And that is it. JBoss will deploy the persistence unit automatically and you can reference it directly, without the need for creating a new one.

What if I don't want to use the container-managed entity manager factory?

Since the persistence unit deployment process takes place automatically, if you don't want to use the container managed entity manager factory and instead opt for creating a Spring-based one, you need to prevent JBoss from doing the deployment. This can be done in a number of ways - either by renaming the persistence unit file and using the 'persistenceXmlLocation' atrribute as shown below.

Using an alternative persistence definition location


You can also use the META-INF/jboss-ignore.txt file as an alternative to renaming. Simply create such a file and include the line below.

The wrap-up

When using Spring and JPA on JBoss, you can opt between the following strategies:

  1. Container-managed entity manager factory + JTA transactions - requires the least amount of configuration to set up, and it is based on functionality supplied automatically by the application server. It is worth keeping in mind that in a clustering scenario, this option ensures that the configuration for distributing the secondary-level cache will be automatically provided by the application server. 
  2. Spring-managed entity-manager factory + JTA transactions - still using JTA, requires additional configuration for setting up the application server. This is an option to consider if your application uses @Transactional(readOnly=true), as container-managed EntityManagerFactories will not honour that option.
  3. Spring-managed entity-manager factory + local transactions - works in an identical way is an a servlet container.

Wednesday, May 26, 2010

JBoss/Spring webinar on June 2nd

I'm happy to invite everyone to attend the "Spring into JBoss" webinar which will take place on June 2nd, 2010. More details, here.

See you there, or download it (it will be recorded!).

Wednesday, May 19, 2010

What's up with the title?

It's best to set things straight from the start: who's the demon and what's up with the second kind?

The blog title is a reference to a story from The Cyberiad by Stanislaw Lem,  called "The Sixth Sally, or How Trurl and Klaupacius Created a Demon of the Second Kind to Defeat the Pirate Pugg".  Said pirate was most unusual: he would capture crews in order to rob them not of doubloons, but of stories. He was , you see, hungry for information - and any new piece of it would do. Now, Trurl and Klapaucius, brilliant engineers as they are (and robotic if we are at that) would punish him in the cruelest way possible - yet perfectly sensible (if you are an engineer as I am).

The two inventors end up constructing a more advanced version of Maxwell's demon (hence the second kind): not only that it can make observations and rational decisions on molecule speeds, but it can also extract meaningful information from the apparently meaningless chaos of molecule movement. Very soon, the pirate was overloaded with information (and physically drowned in printed paper). The information that the Demon extracted was factually correct, but while it wasn't quite meaningless drivel, it wasn't very far from that either. Recipe for ion crumpets? What were the insults which Pope Um of Pendora heaped upon Antipope Mlum of Porking? Come on. 

While I'm not planning to drown anyone with information, nor do I have the skills of extracting genuine information from chaos, the title is a play on the wide range of topics that the blog covers. 

And ... there we go!