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.
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"/>
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>
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"/>