3.2 Middle Tier Highlights

In the middle tier of GreenPages, the DataSource bundle greenpages.db constructs a DataSource and publishes it in the service registry and the JPA bundle greenpages.jpa uses the datasource to define a JPA entity manager which provides an object-relational mapping between directory listings and the database. The JPA bundle also uses declarative transaction management to ensure its persistence operations are performed inside transactions.

DataSource

The file src/main/resources/META-INF/spring/module-context.xml in the greenpages.db project declares the Spring p-namespace:

<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd"
       xmlns:p="http://www.springframework.org/schema/p">

which is then used to define properties of a datasource bean:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
      p:driverClassName="org.h2.Driver" p:url="jdbc:h2:~/greenpages-db/greenpages"
      p:username="greenpages" p:password="pass"
      init-method="createDataSource" destroy-method="close"/>

The file src/main/resources/META-INF/spring/osgi-context.xml publishes the datasource bean as a service in the service registry using Spring DM:

<osgi:service ref="dataSource" interface="javax.sql.DataSource"/>

EntityManager

The greenpages.jpa.JpaDirectory class in the folder src/main/java of the greenpages.jpa project uses the @Repository annotation to make it eligible for Spring DataAccessException translation (which abstracts implementation-specific persistence exceptions to protect the application from details of the persistence implementation):

@Repository
final class JpaDirectory implements Directory {

and also declares an entity manager which will be injected by Spring:

@PersistenceContext
private EntityManager em;

The file src/main/resources/META-INF/spring/module-context.xml in the greenpages.jpa project declares an entity manager factory based on EclipseLink JPA:

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
      p:dataSource-ref="dataSource">
      <property name="jpaVendorAdapter">
            <bean id="jpaVendorAdapter"
                  class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"
                  p:databasePlatform="org.eclipse.persistence.platform.database.HSQLPlatform"
                  p:showSql="true"/>
      </property>
</bean>

The same file enables scanning for annotations, including @PersistenceContext:

<context:annotation-config/>

enables load-time weaving, which is needed by the entity manager factory:

<context:load-time-weaver aspectj-weaving="on"/>

and specifies a bean post processor to perform exception translation for @Repository classes:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

The file src/main/resources/META-INF/persistence.xml defines a persistence unit for a JpaListing directory listing class.

<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
             http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">

      <persistence-unit name="GreenPages" transaction-type="RESOURCE_LOCAL">
            <class>greenpages.jpa.JpaListing</class>
      </persistence-unit>

</persistence>

The file src/main/resources/META-INF/orm.xml defines an entity mapping for the JpaListing class.

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
                 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
                 version="1.0">
      <package>greenpages.jpa</package>
      <entity class="greenpages.jpa.JpaListing" name="Listing">
            <table name="LISTING"/>
            <attributes>
                  <id name="listingNumber">
                        <column name="LISTING_NUMBER"/>
                        <generated-value strategy="TABLE"/>
                  </id>
                  <basic name="firstName">
                        <column name="FIRST_NAME"/>
                  </basic>
                  …
            </attributes>
      </entity>
</entity-mappings>

Transaction Management

The greenpages.jpa.JpaDirectory class in the folder src/main/java of the greenpages.jpa project uses the @Transactional annotation to provide transaction demarcation (beginning and committing a transaction around each method in this case):

@Transactional
…
final class JpaDirectory implements Directory {

The file src/main/resources/META-INF/spring/module-context.xml enables AspectJ weaving for transaction demarcation:

<tx:annotation-driven mode="aspectj"/>

and specifies that the Spring JpaTransactionManager should be used and associated with the entity manager factory:

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