Last week I created an introductory post on using OpenJPA as your JPA implementation, which is available here. This week I wanted to add onto this by adding a relationship and some simple queries.
So in this example, I have built on last weeks Customer entity. I have added an Address entity, which is referenced from Customer as a residential address and a postal address. Residential address is required, hence it is a input into the Customer constructor, and the Postal address is optional. Once again I have followed a Test Driven Development (TDD) approach and the methods are tested using JUnit.
As always I have used Maven to do the build and manage dependencies and I have used Liquibase as per my previous example to manage the database tables and test data.
The full source for the project is available on GitHub at https://github.com/craigew/JPARelationships.
First off the new entity created is called Address and is a very simplistic representation of an address as a basic POJO with @Entity annotation.[gist https://gist.github.com/craigew/6742083 /]
Because I have created the new entity, which I want to be managed by OpenJPA, I must add the following line to the persistence.xml file found in the META-INF folder.[gist https://gist.github.com/craigew/6742118 /]
Next I added the relationship to the Customer entity as a residential address and a postal address. As I stated before, the residential address is required whereas the postal address is optional. This is specified with the optional attribute in the @OneToOne annotation. The @JoinColumn annotation refers to the foreign-key on the Customer table.[gist https://gist.github.com/craigew/6742150 /]
Even though I have added the additional fields to the customer entity, the methods I created last week in the CustomerManagementService remain unchanged. JPA handles the inserting and updating of the new address fields for us.
What I did do, was I added the ability query for customer to the CustomerManagement service. So in order to enable this, I added the following method to the DataAccess class to hide the scaffolding code.[gist https://gist.github.com/craigew/6742218 /]
This method is then simply referenced from the CustomerManagementService, to return a typed list of all Customers, or all Customers in a country.[gist https://gist.github.com/craigew/6742245 /]
And lastly, the Customer tests look like the following.[gist https://gist.github.com/craigew/6742269 /]
Now that I have got a grasp of how JPA is implemented I will be refactoring the domain model into a more appropriate Customer and Address using Archetypes. And then expose these methods using a RESTful API to represent a simplistic Hexagonal architecture.
As always if you find this useful, please give me a like ;-).