I have been using Hibernate JPA, with a Java Generics based data access layer for some time now. But each time I go to a new project, I find that I have to do quite a bit of rework just to integrate this component. So what I wanted to do, is find a way to create a separate component, that was fully tested, but could be included into a project specific component for each new project, with minimal duplication and hassle.

Required Configuration files:

common-data-services eclipse package view
common-data-services eclipse package view

The required configuration files where:

  • META-INF/persistence.xml: JPA Configuration
  • applicationContext-common-data-services.xml: common DAO declarations
  • application-jpa.xml: Spring, JPA and Hibernate declarations
  • hibernate.cfg.xml: Hibernate properties

I wanted to include all the configuration files that where required into the common-data-services jar, but found that persistence.xml was required to build and test, so I had to exclude it from the final jar in my pom.xml :

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                  <strong>&lt;excludes&gt;
                      &lt;exclude&gt;**/persistence.xml&lt;/exclude&gt;
                  &lt;/excludes&gt;</strong>
                &lt;/configuration&gt;
            &lt;/plugin&gt;

I did this, because if I left this in the common-data-services jar, then any project specific jar would not be able to add inherited domain objects. The other 3 configuration files could be included in this jar

Required Java Files:

common-data-services eclipse package view (java files)
common-data-services eclipse package view (java files)

The required Java files where:

  • src/main/java/com.**.dao.*: Generics based Data Access Object
  • src/main/java/com.**.domain.*: Annotated
  • src/test/java/com.**.dao.jpa.*: DAO specific test cases
  • src/test/java/com.**.domain.*: Domain specific test cases

I did this, because if I left this in the common-data-services jar, then any project specific jar would not be able to add inherited domain objects. Such as, I wanted all users of this component to have:

  • IdentifiedObject: Base Class for all domain Objects
  • IdentifiedObjectListener: Listener for IdentifiedObject class.
  • StringIdentifiedObject: Base Class for all String Identified domain Objects
  • StringIdentifiedObjectListener: Listener for StringIdentifiedObject class.

I was trying to have something that was reusable to where projects did not have to re-create the wheel each time they wanted to implement data services.

Now, when I create a project specific data-services component, I can then just add the common-data-services as a dependency:

        &lt;dependency&gt;
            &lt;groupId&gt;com.baselogic.services&lt;/groupId&gt;
            &lt;<strong>artifactId&gt;common-data-services&lt;/artifactId&gt;</strong>
            &lt;version&gt;3.0-SNAPSHOT&lt;/version&gt;
            &lt;scope&gt;compile&lt;/scope&gt;
        &lt;/dependency&gt;

When I create the component, can see her, that I only need the META-INF/persistence.xml

project specific data-services component in eclipse
project specific data-services component in eclipse

In the project specific persistence.xml, I had to add the classes from my common-data-services jar, so those tables would get created by Hibernate

    &lt;persistence-unit name="ApplicationEntityManager" transaction-type="RESOURCE_LOCAL"&gt;
        &lt;!--
            It appears that in order to create additional
            tables from other JAR's, we need to declare them here.
        --&gt;
        <strong>&lt;class&gt;com.baselogic.domain.User&lt;/class&gt;</strong>
        &lt;class&gt;com.baselogic.domain.security.Authority&lt;/class&gt;
        &lt;class&gt;com.baselogic.domain.security.UserDetails&lt;/class&gt;

I did include an src/main/resources/import.xml in this module. This way, after the common-data-services classes are included, and my project data services TABLES where create by hibernate, I can add reference data here to seed my database for testing purposes.

Conclusion:

It is easy to include all common data service code into a reusable component(jar), then leverage that in a project specific data services implementation. The only duplication is to add a persistence.xml into teh common-data-services component, but exclude it from the final package.

Mick Knutson

Java, JavaEE, J2EE, WebLogic, WebSphere, JBoss, Tomcat, Oracle, Spring, Maven, Architecture, Design, Mentoring, Instructor and Agile Consulting. http://www.baselogic.com/blog/resume

View all posts

Java / JavaEE / Spring Boot Channel

BLiNC Supporters

BLiNC Adsense

Archives

Newsletter