In this tutorial I would like to show you, how you can build a modular maven application together with working JPA persistence. That means, at the end of the tutorial you will be able to fetch your entities from several jar files into one application.
The use-case is quite common. Assume you want to build a modular application where each module contains one layer of your application. Typically, I’ve got the following layers in my applications:
- Entity (jar)
- DAO (jar)
- Service (jar)
- Controller + UI (war)
That would give you four maven projects. Three of them will be packaged as jar-file and the UI layer will be packaged as war-file. The entities will reside in the entity project.
For JPA persistence, you need a persistence.xml file, to declare your persistence-units. I won’t declare the persistence.xml file in the entity project, because other projects could depend on the entity project too and besides this, they could declare additional entities on their own. So, if we would store the persistence.xml in the entity project that would’nt work, because only one persistence.xml can be used by the application.
So, let’s start and build an application which can fetch entities from several jar-files.
You should be familiar with the following topics:
In the following, we will build a simple application which consists of three maven projects. For simplicity, I will omit the service layer and put the entities and DAO’s in the same project.
The first maven project (modular-jpa-persistence) acts as a parent and declares the other two projects as modules.
The second one (modular-jpa-persistence-entity) is the project which holds the entities and DAOs .
The third project (modular-jpa-persistence-web) contains the UI as well as the controllers.
Our final project structure would be something like this:
Defining the persistence.xml
We define our persistence.xml file in the UI project under the folder src/main/resources/META-INF. In the persistence.xml there is a jar-file element which seems pretty much useful. The downside of this element is, that it requires an absolute path to a jar-file. With standard JPA it is not possible to use that jar-file element with an relative path when packaging the application as war-file.
Fortunately, in our applicate we’re using spring and that will help us out. With spring we can use an relative path to reference our entities jar. To get this working, we can use the following:
Ok, what does that mean? When we build our entity project, it will be called modular-jpa-persistence-entity-0.0.1-SNAPSHOT.jar. When building the UI project the entity jar will be put into our web application in the folder [webapplication]/WEB-INF/lib/. The classpath: string tells spring, to start searching for the jar at the classpath location which is [webapplication]/WEB-INF/classes/. So, to reference the correct jar, we first have to navigate one folder up, then browsing into the lib folder and then we will find our entity jar.
This will work fine for production, when the application is packaged together. If we want to use unit tests, we still have to reference the entity jar as absolute path, because this is a multi-module project and we can’t guess where the final entity jar will be stored.
So the best way to solve this, is to write the jar-file element in the persistence.xml at the compile time with maven. This can be done with maven profiles, please see my maven-profile tutorial for further information.
With the help of spring it is possible to load entities from several jar-files. It only requires some configuration and using the jar-file element in the persistence.xml. To fully understand the example project, it’s the best to have a look at the source-code and run the application. Don’t miss the readme file which will help you to get the project up and running.
You can find a full working example at GitHub.