Contact Application DAO

David Winterfeldt

2012


This is the DAO module for the Contact Application and has a basic JPA configuration with inheritance. It uses Spring Data JPA for it's repositories and to set audit information when persisting and entity. JPA optimistic locking has also been added. This module is based on Spring Data JPA.

1. Spring Configuration

The first Spring configuration file sets up the DataSource, what SQL scripts should be run at startup, and any property placeholder files that should be loaded.

META-INF/spring/db/dao-datasource-context.xml
                
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                           http://www.springframework.org/schema/context 
                           http://www.springframework.org/schema/context/spring-context-3.2.xsd
                           http://www.springframework.org/schema/util 
                           http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <bean id="dataSource"
          class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="${jdbc.driver.class}" p:url="${jdbc.url}"
          p:username="${jdbc.username}" p:password="${jdbc.password}"
          p:initialSize="${jdbc.initial.size}" 
          p:minIdle="${jdbc.min.idle}" p:maxIdle="${jdbc.max.idle}" 
          p:maxActive="${jdbc.max.active}"
          p:timeBetweenEvictionRunsMillis="${jdbc.time.between.eviction}" 
          p:minEvictableIdleTimeMillis="${jdbc.min.evictable.idle}" 
          p:testOnBorrow="true" 
          p:validationQueryTimeout="${jdbc.validation.query.timeout}"
          p:validationQuery="${jdbc.validation.query}" />

    <beans profile="hsql">   1
        <context:property-placeholder location="classpath:/sql/hsql.properties,classpath*:META-INF/config/**/*.properties" /> 2

        <util:list id="databaseScriptsList" value-type="org.springframework.core.io.Resource">
            <value>classpath:/sql/hsql/schema.sql</value>
            <value>classpath:/sql/hsql/security_schema.sql</value>
        </util:list>
    </beans>

    <beans profile="postgresql"> 3
        <context:property-placeholder location="classpath:/sql/postgresql.properties,classpath*:META-INF/config/**/*.properties,file:contact-app*.properties" /> 4

        <util:list id="databaseScriptsList" value-type="org.springframework.core.io.Resource" />
    </beans>

</beans>
                
            
1 HSQL DB Spring profile.
2 Context property placeholder is configured to explicitly load the hsql.properties file and load all properties under META-INF/config.
3 PostgreSQL DB Spring profile.
4 Context property placeholder is configured to explicitly load the postgresql.properties file and load all properties under META-INF/config. It also will load any property files from where the application is started that start with 'contact-app' and end with '.properties'.

The second Spring configuration file configures Spring Data JPA, and it's entity auditing feature. It also configures transactions, the entity manager, and runs any SQL scripts added to the 'databaseScriptsList' bean. The persistence unit name for JPA is set using the properties files that were loaded in the Spring profiles in the previous Spring Configuration. There is a persistence unit configuration for HSQL DB and PostgreSQL in the persistence.xml.

META-INF/spring/db/dao-jpa-context.xml
                
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd
                           http://www.springframework.org/schema/data/jpa
                           http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <jpa:repositories base-package="org.springbyexample.contact.orm.repository" />

    <!-- auditing -->
    <jpa:auditing auditor-aware-ref="auditorAware" />
    <bean id="auditorAware" class="org.springbyexample.contact.orm.entity.AuditorAwareImpl" />
    
    <tx:annotation-driven />
        
    <bean id="transactionManager" 
          class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory"/>
          
    <bean id="entityManagerFactory" 
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    	  p:dataSource-ref="dataSource"
          p:persistenceUnitName="${jpa.persistence.unit.name}" 1
          depends-on="dataSourceInitializer">
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">${jpa.show.sql}</prop>
                <prop key="hibernate.generate_statistics">false</prop> 
                <prop key="hibernate.cache.use_second_level_cache">${jpa.cache.use_second_level_cache}</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
            </props>
        </property>
    </bean>

    <bean id="dataSourceInitializer" 
          class="org.springframework.jdbc.datasource.init.DataSourceInitializer"
          p:dataSource-ref="dataSource">
        <property name="databasePopulator">
            <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator"
                  p:scripts-ref="databaseScriptsList"
                  p:sqlScriptEncoding="UTF-8" />
        </property>
    </bean>

</beans>
                
            
1 The persistence unit name is set using a property placeholder, which loaded the appropriate name based on the Spring DB profiles.