Configuration
Configuration
Maven
When using a database, JPA, and integration of JPA and Spring, we should
add following dependencies based on chapter 9’s configuration: (We add
spring-web and cblib for Spring framework which is explained in
previous chapter.)
<properties>
<zk.version>8.0.0-Eval</zk.version>
<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
<packname>-${project.version}-FL-${maven.build.timestamp}</packname>
<spring.version>3.1.2.RELEASE</spring.version>
</properties>
...
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- JPA(Hibernate) and HSQL dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.6</version>
</dependency>
...
- Line 5, 16~17: Spring provides a module to integrate several ORM (Object Relation Mapping) frameworks, integrating JPA requires this dependency.
- Line 27~28: There are various implementations of JPA specification, we choose Hibernate’s one which is the most popular.
- Line 32~33: For using HSQL, we should add its JDBC driver.
Persistence Unit Configuration
We should describe persistence unit configuration in an XML file called
persistence.xml and we need to specify name, transaction-type, and
properties. The properties are used by persistence provider
(Hibernate) to establish database connection and setup vendor specific
configurations.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="myapp" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.connection.driver_class"
value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.connection.url"
value="jdbc:hsqldb:file:data/store" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
- Line 3: The persistence unit name
myappwill be used later in Spring configuration.
Deployment Descriptor
You aren’t required to add any special configuration for JPA to work.
Here we add a Spring provided OpernEntityMangerInViewFilter to resolve
an issue caused by lazy-fetching in one-to-many mapping. Please refer to
Developer’s Reference
for this issue in more detail.
Extracted from web.xml
...
<!-- Spring configuration -->
<!-- Initialize spring context -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Enable webapp Scopes-->
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<filter>
<filter-name>OpenEntityManagerInViewFilter
</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
Entity Annotation
Before storing objects into a database, we should specify OR (object-relation) mapping for Java classes with meta data. After JDK 5.0, we can specify OR mapping as annotations instead of XML files. JPA supports configuration by exception which means that it defines default for most cases of application and users only need to override the configuration value when it is exception to the default, not necessary.
First, annotate the class with @Entity to turn it into an entity, and
annotate the member field for primary key with @Id. All other
annotations are optional and we use them to override default values.
Todo class used in todo-list management
@Entity
@Table(name="apptodo")
public class Todo implements Serializable, Cloneable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Integer id;
boolean complete;
@Column(nullable=false,length=128)
String subject;
@Column(nullable=false,length=128)
@Enumerated(EnumType.ORDINAL)
Priority priority;
@Temporal(TemporalType.TIMESTAMP)
Date date;
String description;
//omit getter, setter, hashCode(), equals() and other methods
}
Spring Beans Configuration
Spring JPA , available under the org.springframework.orm.jpa package,
offers integration support for Java Persistence API. According to Spring
framework reference, there are three options for JPA setup. We choose
the simplest one.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<context:component-scan base-package="org.zkoss.essentials" />
<!-- jpa(hibernate) configuration -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myapp"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven />
</beans>
- Line 16,17: The simplest Spring setup for JPA is to add a
LocalEntityManagerFactoryBeanwhich create aEntityManagerFactoryfor simple deployment environments and specify itspersistenceUnitNameproperty. - Line 18: Set property
persistenceUnitNamewith the name we specified inpersistence.xml. - Line 21,26: Enable Spring’s declarative transaction management.