Over the last week or so I have been working on getting JBoss, JPA and Spring working together. When I wrote my previous entry I thought I had everything working. Well, up to that point I had not tried to save a record to the database. When I tried to do that nothing happened. This lead to a long debugging process that felt more like a hopeless goose chase at times. With the help of Costin Leau on the Spring forum I finally got it working, but it was quite the trial. Not many people have attempted to get this combination working. One of the things that complicated my setup is that my data access objects are a descendant of the JpaDaoSupport class provided in the Spring framework.
Getting them all working together is a matter of putting everything in the right place. I'm deploying as an ear file containing: a jar file with all of my JPA entities and dao's in it; and a war file that has my jsp's, other web resources, view classes and a jar file containing all of my service beans. I also have a lib directory in my ear file that contains the spring.jar file and the AspectJ jar files. This is very important. My ear file looks like this:
ear - - quadran.war
| - quadran-data.jar <-- my persistence archive
| - lib
| - spring.jar
| - aspectjrt.jar
| - aspectjweaver.jar
| - META-INF
| - MANIFEST.MF
I'm using the context loader listener to load my Spring application context from the /WEB-INF/lib/ directory of my war file. I started with putting the Spring and AspectJ jar files in this directory but ran into class loader issues. So in order to expose the Spring and AspectJ jar files to both the data jar and the war I added a classpath entry to the MANIFEST.MF file of both files. The MANIFEST files looks something like this:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.0
Created-By: 1.5.0_06-64 ("Apple Computer, Inc.")
Class-Path: ./lib/vr-utils.jar ./lib/spring.jar ./lib/aspectjweaver.ja
r ./lib/aspectjrt.jar
I create this using the manifest argument to the ant jar task.
With this in place the ear loads, JBoss sets up the JPA entities, the war loads and the Spring ApplicationContext is created.
In order to get JPA to save things to the database it is necessary to wrap them in a transaction. I do this with the following in my applicationContext.xml file:
<!-- JPA EntityManagerFactory setup -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="quadran" />
</bean>
<!-- Jpa Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:advice id="managerTxAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="managerMethods"
expression="execution(* net.vitarara.quadran.core.business.*Manager.* (..))" />
<aop:advisor advice-ref="managerTxAdvice" pointcut-ref="managerMethods" />
</aop:config>
The entityManagerFactory is used by the DAO's to access the JPA EntityManager. The transactionManager is used to manage the transactions, which are defined using the tx:advice and aop:config tags. My tx:advice tag simply configures transactions on all methods. I will narrow this scope in the future, but during my debugging process I decided to cast a wide net. The aop:config uses the aop:pointcut method of selecting what classes to apply the tx:advice to. I have chosen to apply this advice to any method of any class in the net.vitarara.quadran.core.business package that ends in Manager. These classes are actually interfaces, which has the effect of applying this configuration to any class that implements those interfaces.
Deployment of the ear seems to take a while. It seems that JBoss needs to do a lot of thinking to figure out that the Classpath statements in the MANIFEST file refer to jars in the ear file. I may look at possibly adding these to the $JBOSS_HOME/$SERVER_CONFIG/lib directory, but that will take some serious experimentation before I'd really be comfortable with it.
If you know of a better way to get JBoss, JPA and Spring working together I'd love to know it.
Recent comments
6 weeks 4 days ago
7 weeks 2 days ago
7 weeks 5 days ago
8 weeks 5 days ago
9 weeks 23 hours ago
9 weeks 1 day ago
9 weeks 5 days ago
12 weeks 6 days ago
13 weeks 4 days ago
13 weeks 4 days ago