Now that we have introduced JPA, its role, and the benefits of using Entities, we can now focus on how to configure our Spring application to handle them.
As we said earlier, the JPA is a specification. Choosing a persistence provider (Hibernate, OpenJPA, TopLink, and so on) or a database provider for an application won't be a commitment as long as they match the standards.
We will see that our JPA configuration in Spring is done by defining two beans: datasource and entityManagerFactory. Then, the optional Spring Data JPA
library offers a JPA
repository abstraction that is able to surprisingly simplify some database operations.
v3.x.x
branch.csmcore-config.xml
:<jpa:repositories base-package="edu.zc.csm.core.daos" /> <bean id="dataSource" class="org.sfw.jdbc.datasource.DriverManagerDataSource> <property name="driverClassName"> <value>org.hsqldb.jdbcDriver</value> </property> <property name="url"> <value>jdbc:hsqldb:mem:csm</value> </property> <property name="username"> <value>sa</value> </property> </bean> <bean id="entityManagerFactory" class="org.sfw.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="jpaData"/> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <beanclass="org.sfw.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> <property name="jpaProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.HSQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="hibernate.default_schema">public</prop> </props> </property> </bean>
org.springframework.data:spring-data-jpa
(1.0.2.RELEASE)org.hibernate.javax.persistence:hibernate-jpa-2.0-api
(1.0.1.Final)org.hibernate:hibernate-core
(4.1.5.SP1)Adding this dependency causes the Maven enforcer plugin to raise a version conflict with jboss-logging
. This is why jboss-logging has been excluded from this third-party library and referenced as a dependency on its own:
org.hibernate:hibernate-entitymanager
(4.1.5.SP1)
jboss-logging
has also been excluded from this third-party library because, it is now referenced as a dependency on its own:
org.jboss.logging:jboss-logging
(3.1.0.CR1)org.hsqldb:hsqldb
(2.3.2)org.javassist:javassist
(3.18.2-GA)org.apache.commons:commons-dbcp2
(2.0.1)We are going to review these three configuration points: the dataSource bean, the entityManagerFactory bean, and Spring Data JPA.
Because creating a database connection is time consuming, especially through the network layers, and because it is sensible to share and reuse an opened connection or a connection pool, a datasource has the duty of optimizing the use of these connections. It is a scalability indicator and also a highly configurable interface between the database and the application.
In our example, Spring manages the datasource just as for any other bean. The datasource can be created through the application or can be accessed remotely from a JNDI lookup (if the choice is made of giving up the connection management to the container). In both cases, Spring will manage the configured bean, providing the proxy that our application needs.
Also in our example, we are making use of the Apache Common DBCP 2 datasource (released in 2014).
As its name suggests, the EntityManagerFactory
bean produces entity managers. The configuration of EntityManagerFactory
conditions the entity manager behavior.
The configuration of the EntityManagerFactory
bean reflects the configuration of one persistence unit. In a Java EE environment, one or more persistent units can be defined and configured inside a persistence.xml
file, which is unique in the application archive.
In a Java SE environment (our case), the presence of a persistence.xml
file is made optional with Spring. The configuration of the EntityManagerFactory
bean almost completely overrides the configuration of the persistence unit.
The configuration of a persistence unit, and, therefore, of an EntityManagerFactory
bean, can either declare the covered Entities individually or scan packages to find them.
A persistence unit can be seen as a subarea among the horizontal scaling ecosystem. A product can be broken down into wars (web archives) for each the functional area. Functional areas can be represented with a selection of Entities that are delimited by a persistence unit.
The main point is to avoid creating Entities that overlap different persistence units.
We are about to use some very useful tools from the Spring Data JPA project. These tools aim to simplify the development (and maintenance) of the persistence layers. The most interesting tool is probably the repository abstraction. You will see that providing implementations for some database queries can be optional. An implementation of the repository interface will be generated at runtime from the method signatures if they match a standard in their declarations.
For example, Spring will infer the implementation of the following method signature
(if the User
entity has a String userName
field):
List<User> findByUserName(String username);
A more extended example of our bean configuration on Spring Data JPA could be the following:
<jpa:repositories base-package="edu.zipcloud.cloudstreetmarket.core.daos" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/>
As you can see, Spring Data JPA contains a custom namespace that allows us to define the following repository beans. This namespace can be configured as follow:
base-package
attribute in this namespace is mandatory to restrict the lookup for Spring Data repositories.entity-manager-factory-ref
attribute is optional if you have only one EntityManagerFactory
bean configured in ApplicationContext
. It explicitly wires EntityManagerFactory
, which is to be used with the detected repositories.transaction-manager-ref
attribute is also optional if you have only one PlatformTransactionManager
bean configured in ApplicationContext
. It explicitly wires PlatformTransactionManager
, which is to be used with the detected repositories.More details can be found about this configuration on the project website at:
http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/jpa.repositories.html.