Configuring the Java Persistence API in Spring

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.

Getting ready

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.

How to do it...

  1. From the Git Perspective in Eclipse, check out the latest version of the v3.x.x branch.
  2. As previously introduced, we have added a couple of beans to the Spring configuration file (in the core module) 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>
  3. Finally, the following dependencies have been added to the parent and core projects:
    • 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)

How it works...

We are going to review these three configuration points: the dataSource bean, the entityManagerFactory bean, and Spring Data JPA.

The Spring-managed DataSource bean

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).

Tip

In a production environment, it might be a good idea to switch to a JNDI-based datasource, such as the native Tomcat JDBC pool.

The Tomcat website clearly suggests a significant gain in performance when using the Tomcat JDBC pool instead of DBCP1.x on highly concurrent systems.

The EntityManagerFactory bean and its persistence unit

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.

Note

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.

The Spring Data JPA configuration

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:

  • Providing a base-package attribute in this namespace is mandatory to restrict the lookup for Spring Data repositories.
  • Providing an 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.
  • Providing a 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.

See also

  • HikariCP DataSource: HikariCP (from its BoneCP ancestor) is an open source Apache v2 licensed project. It appears to perform better in speed and reliability than any other DataSource. This product should probably be considered considered when choosing a datasource nowadays. Refer to https://brettwooldridge.github.io/HikariCP for more information on this.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset