Wednesday, August 29, 2012

Spring Framework with Hibernate JPA - ApplicationContext


Continued from Spring Framework with Hibernate JPA

Notice the property variables in the ApplicationContext.xml.
Notice the bean specifying the location of configuration.properties file whose property definitions can be used for substitution into the ApplicationContext.xml file.

ApplicationContext.xml


configuration.properties file
zzz.rambutan.driver=oracle.jdbc.driver.OracleDriver
zzz.rambutan.url=jdbc:oracle:thin:@holymoly.kacang.putty
zzz.rambutan.user=durian
zzz.rambutan.password=langsat
zzz.rambutan.hibernate.dialect=org.hibernate.dialect.OracleDialect
zzz.rambutan.hibernate.showSql=true

To be continued ....

Spring Framework with Hibernate JPA

The few articles prior to this discussed the conjunctive use of
  • GWT as REST client
  • JAX-RS REST service
  • JPA2
  • A POJO data transfer schema shared across the three frameworks

This article furthers the conjunction by including the deployment of Spring Framework. Therefore, the technology conjunctivitis now comprises
  • GWT
  • RestyGWT
  • RestEasy
  • Hibernate 3.x in JPA 2.x mode
  • Spring Framework's inversion of control to configure Hibernate.
Reason for Spring Framework
The reason for including Spring Framework is to exploit its ability to turn away from Hibernate's persistence.xml hard-coded values towards Spring's ability to make the persistence definition agile and adaptive. I should have used the term "dynamic" definition rather than agile/adaptive. 

However, being dynamic would mean we would change those configuration in the middle of playing the game. Not so, we only want to adaptively define those values during application loading. We want to place variables in Hibernate connectivity that are resolved during application loading.

So that we do not have to manually, or write an application within an application to, modify persistence.xml hard-coded values when deploying the app across disparate systems.

The issue at hand is
how to use Spring Framework to configure Hibernate as a JPA 2.x provider.

The usual persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="obamacare"
      transaction-type="RESOURCE_LOCAL">
    <provider>
      org.hibernate.ejb.HibernatePersistence
    </provider>
    <exclude-unlisted-classes>
      false
    </exclude-unlisted-classes>
    <!-- Scan for annotated classes and Hibernate mapping XML files -->
    <properties>
      <property name="hibernate.archive.autodetection"
        value="class, hbm"/>
      <property name="javax.persistence.jdbc.driver"
        value="oracle.jdbc.driver.OracleDriver"/>
      <property name="javax.persistence.jdbc.url"
        value="jdbc:oracle:thin:@holymoly.kacang.putty"/>
      <property name="javax.persistence.jdbc.user"
        value="durian"/>
      <property name="javax.persistence.jdbc.password"
        value="langsat"/>
      <property name="hibernate.dialect"
        value="org.hibernate.dialect.OracleDialect"/>
     <property name="hibernate.show_sql"
        value="true"/>
    </properties>
  </persistence-unit>
</persistence>

The goal is to conceptually be able to do this:
    <properties>
      <property name="hibernate.archive.autodetection"
        value="class, hbm"/>
      <property name="javax.persistence.jdbc.driver"
        value="${zzz.rambutan.driver}"/>
      <property name="javax.persistence.jdbc.url"
        value="${zzz.rambutan.url}"/>
      <property name="javax.persistence.jdbc.user"
        value="${zzz.rambutan.user}"/>
      <property name="javax.persistence.jdbc.password"
        value="${zzz.rambutan.password}"/>
      <property name="hibernate.dialect"
        value="${zzz.rambutan.hibernate.dialect}"/>
     <property name="hibernate.show_sql"
        value="${zzz.rambutan.isDebug}"/>
    </properties>

However, neither JPA nor Hibernate is able to accept variables in the persistence.xml file. Therefore, we would have to depend on Spring's ApplicationContext.xml ability to accept variables.