Archive

Posts Tagged ‘spring’

JPA 2.0 and Spring 3.0 with Maven

January 9, 2010 27 comments

I’m currently updating WicketCool to use Spring 3.0, JPA2.0 and latest Wicket. Here is a short summary of my research, a quick tutorial showing how to jump into Spring3.0 + JPA2.0 development using Maven.

1. Dependencies

a) Spring

To use 3.0 release of the Spring framework you can’t no longer add one dependency as you used to do it

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring</artifactId>
   <version>2.5.6</version>
</dependency>

This will no longer work. Spring framework is divided into 20 modules:

If you create web appliactions, you will probably need modules listed below:

  1. all from Core Container: Beans, Core, Context and Expression Language
  2. AOP
  3. from Data Access/Integration: Transactions, ORM
  4. from Web: Web (even if you don’t use SpringMVC, you still might consider OpenEntityManagerInViewFilter which is inside Web module
  5. Test

Thus set of dependencies that you need to include in your pom.xml are:

<properties>
 <spring.version>3.0.0.RELEASE</spring.version>
</properties>

<dependencies>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-tx</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>${spring.version}</version>
 </dependency>
 <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring.version}</version>
 </dependency>
</dependecies>

b) JPA 2.0

Now that we have Spring dependencies sorted out, we can look at the JPA2.0.  We must remember that JPA itself is only standard, thus when setting dependencies we are really choosing the provider. I could go with Hibernate or EclipseLink. Hibernate is still in beta state and EclispeLink is a reference implementation of the standard, so I thought that EclipseLink is a good way to go. However after recent discoveries (which took me quite some to figure out by the way), I thought I will stick with the Hibernate’s beta.

What is new in Hibernate’s recent release is that you no longer need to define dependencies to core, annotations, commons-annotations ect. It is now only one, single dependency.  Second dependency is the API of the standard.

<dependencies>
  <dependency>
    <groupId>org.hibernate.java-persistence</groupId>
    <artifactId>jpa-api</artifactId>
    <version>2.0-cr-1</version>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.5.0-Beta-2</version>
  </dependency>
</dependencies>

You might also need to add JBoss repository:

<repositories>
 <repository>
   <id>JBoss Repo</id>
   <url>http://repository.jboss.com/maven2</url>
 </repository>
</repositories>

2. Configuration

The simples application context configuration file can look like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 <!-- holding properties for database connectivity /-->
   <context:property-placeholder location="classpath:jdbc.properties"/>
   <!-- enabling annotation driven configuration /-->
<context:annotation-config/>
<context:component-scan base-package="wcpackage"/>
   <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean
       class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <bean id="dataSource"
       class="org.springframework.jdbc.datasource.DriverManagerDataSource"
       p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
       p:entityManagerFactory-ref="entityManagerFactory"/>

    <bean id="entityManagerFactory"
       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
       p:dataSource-ref="dataSource"
       p:jpaVendorAdapter-ref="jpaAdapter">
       <property name="loadTimeWeaver">
          <bean
             class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
        <property name="persistenceUnitName" value="wctemplatePU"></property>
    </bean>

    <bean id="jpaAdapter"
         class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
         p:database="${jpa.database}"
         p:showSql="${jpa.showSql}"/>
</beans>

Given that wcpackage is a root package for component scan and wctemplatePU is name of the persistent unit.
Now all we need to do is to define persistence unit in META-INF/persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence">

	<persistence-unit name="wctemplatePU" transaction-type="RESOURCE_LOCAL">
		<properties>
			<property name="hibernate.hbm2ddl.auto" value="validate" />
		</properties>
	</persistence-unit>
</persistence>

And that is basically it. You have Spring configuration and now can use EntityManager in your services classes.

@Repository(value = "userDAO")
public class UserDefaultDAO implements UserDAO {

    @PersistenceContext
    private EntityManager entityManager;

Injected EntityManager will be with transaction-scoped persistence context, resource_local transaction type (meaning transactions used from database not JTA). Hope everything is comprehensive. If you have any questions, please let me know.

See also:

  1. A proper way for JPA entities instantiation
ale macie fajnie
Advertisements
Categories: Other Tags: , , ,