Building easy to use JPA classes

April 11, 2012

Category: Ideal JPA, Techy

Tags: , ,

Continuing on with my previous article, I would go on to discuss about making the JPA classes easy to use for your users, aka the other developers, while making it adhere to the portability constraints I had set out earlier.
Ease of use is achieved by properly encapsulating the domain package classes.  There are generally two types of classes you would find in a domain package:
  • JPA Entity classes
  • A (usually single) Stateless Session Bean that handles the domain operations for the domain.

JPA Entity Classes

Let’s start out with some code for the JPA entity.

Some guidelines that you should gather from the above:

Never expose the primary key

The JPA package must not expose any of its primary keys to the outside.  This allows the flexibility of having different types of primary keys used depending on the current code.  Ideally, you’d only access the domain using a “business key” lookup.  I typically use UUID for the business key as shown above. Using this rule actually helps make the decision whether a class should be part of the package or not. If you need the primary key then you are likely to be in the same domain.  Don’t use efficiency as an excuse to use it.

Convert the data to and from the portable types

As noted in the previous article, we should only store data that can be portably persisted. In the above example, I have provided a few conversions for UUID, Date and a byte[] array. One thing to note is I store those types as Strings as String is a portably persisted data type.

It’s ok to expose your collection

Depending on the situation, for the most part return a modifiable list is okay, but it isn’t best practice because it allows clients to manipulate the data in an unrestricted fashion. So if you want to limit operations on the set you can create additional functions to wrap manipulation the set.  However, if you want the other developers to have the flexibility of doing manipulations using the entire collections API then just return the actual set.

Stateless Session Bean

Let’s start out with some code for the SLSB.

The SLSB is used so you get an entity manager and transaction given to you by the container so you don’t have to deal with it yourself. setEntityManager() is there for JUnit testing.

Primarily you create lookup methods using business keys and convert them to the proper parameters.

This is similar to the Transaction Script in that it hides the persistence details from the user.

Depending on the skill level of the users, you may or may not choose to wrap the “persist” and “merge” operations. In general, I don’t wrap these out of my own laziness, but also because it is a fundamental part of using JPA classes so the users should use them. However, if the users require a non-JPA API interface it isn’t too much extra work.

The there are two times I do wrap them:

  • if the registration of the data is complicated, but that is just for the persist. I still expect updates and deletes to be done using the merge method.
  • if I use a @ManyToOne relationship (sometimes I do because I may require JPA 1.0 compatibility)

Coming up in a couple of weeks, the final installment of the series.