Java Persistence Api Annotation Cheat Sheet

I learned in my years as a software developer that I learn things then better if I try them, create a short application with them. Or I write about them a blog article.

Now I encountered a project where we use JPA2.0 (implementation by Hibernate but this is mostly out of the question) and I need some information about the used annotations — and especially their optional parameters and default values.

So in this article I’ll create a little cheat sheet for myself of the annotations’ attributes and defaults and eventually you can benefit from it too.

As mentioned in the preface I use Hibernate’s implementation of javax.persistence because they have comments and easily downloadable sources into Eclipse. But as I mentioned above I try to stick strictly to the usage of common javax.persistence annotations. The only time I needed some Hibernate specific annotation was JodaTime — but this is another story.

Entity, Table, Column

First of all let’s take a look at the general annotations you use with your Entities.

@Entity has only one optional parameter and it is name. This name is used in the queries. If you not set it, the name will be the name of the Java class. Let’s examine this through a simple example:

@Entity(name = "Customer")
public class CustomerEntity{
// some code omitted
}

As you can see above the CustomerEntity class is an entity with the name Customer. This allows that you can query CustomerEntity objects from the database referencing them as Customer — saving the Entity part in your queries. What you can ask is “Why do you specify Entity in the class name because it is obvious from the annotation?”. The answer could be that this is defined in the project: “Every Entiy’s class name has to end with Entity.” This is a good enough reason — and eventually you can have a Checkstyle which gives you a nice yellow warning if you miss this part. And another reason for the “WHY”: sometimes there are restrictions not to reach your entities outside of your module border — and with the Entity at the end you can see that you should not access this object but get a DTO instead. It is philosophy, every aspect has its own pros and cons. However if you’d like my opinion: you only need DTOs if you need some custom representation of an entity (i.e. in a GUI) or want a subset of data collected from a couple of entities. Otherwise just give away your entities over the borders. I’ve seen some projects where you had to convert every entity into a DTO and it was most of the time just a 1:1 copy in the entity (with .fromDTO and .toDTO methods).

@Table has some optional parameters, which default to an empty String or an empty array (uniqueConstraints).

However sometimes you need to use at least the column property of Table: this tells the implementing JPA library which database table to look at if handling this type of objects. This comes handy if your database table has another name than your Java class (for example you need the tables have a specific prefix or your table/class name would be a keyword in Java or in your database.

For granularity you can specify catalog and schema of the table but I’ve never seen scenarios in my projects where we needed this.

The uniqueConstraints get important if you generate your database tables from your Java classes. Here you can define your unique constraints you’d like to append to this table.

@Column is more interesting because this you use more often to describe some valuable information for your columns: for example different names as in the Java class.

Parameter Desription
name  Defaults to the same column name of the variable. This can change if you plan to make your columns unse an uderscore (“_”) where you use camleCase in your Java class.
unique  It is used within the DDL creation. It is a shourtcut for the @Table’s uniqueConstraints. If you generate your tables outside of your persistence api (for example with Liquibase) then you do not need this parameter.
nullable  Tells if the column is nullable or not. Most os the time you specify the same thing within the database too however it is good to let your fellow developers know that they should not enable a null for this field. And the validation raises an error prior to your database in this case.
insertable  Defines if the column gets included if you call an insert statement with your JPA provider. You can use this to restrict newly inserted lines in the table to be null (or any default value you specify).
updatable  Almost the same than insertable but it is restricted to an update statement.
columnDefinition  Again a parameter for DDL generation: here you can define how to create the column, for example VARCHAR2(25 CHAR) for a string column.
table  Again a nasty thing: here you can define in which table the column is. It defaults to the same table as the entity. In my eyes it is a bad practice to reference a table’s column from another class — naturally there can be an exception for this but it is really seldom to find one.
length  Length of String column. Only Strings, decimals are not modified. It defaults to 255. This means two things: if you have a larger field in the database (say 500 chars) you will be only saving 255 chars. The other is: you have a field with 25 chars in the database and try to save a value of say 50 chars your JPA library lets your query flow through to the database where it returns with a big exception. So beware.
precision  This is only for decimal columns. If you use your JPA library to generate the DDL from your classes be sure to use this parameter for decimal numbers because it is a must.
scale  Another parameter for decimal columns. It sets the scale of the decimal number. However this is not a must for DDL, it defaults to 0 so your decimal number ends up as a round decimal — but nor rounded naturally only the scale is missing.

GeneratedValue, SequenceGenerator

GeneratedVaulues are a really beutiful types for IDs. In my projects however I found everyone is sticking to use Sequences to generate the IDs. So you can handle it yourself and can look up which sequence number comes next. And most of the projects prefer one sequence per ID.

The default generation strategy is AUTO so if you want to use a sequence or a table you need to change this.

The other optional parameter is generator which names the generator defined by SequenceGenerator or TableGenerator.

If you choose to use a SequenceGenerator be sure to use the sequenceName parameter of it (the name is required) because it defaults to one sequence the provider chooses. So if you plan to have a single sequence pro ID and want to know the name of the corresponding sequence use sequenceName and define your own sequence in the database.

The same goes for TableGenerator: the table parameter defines which table is used. And if you use TableGenerator be sure to check the other optional parameters too which make the usage experience better because there are a lot of configurations which default to a provider-chosen value. And this could be a pain in the neck. So I’d say it is a best practice in my eyes to use table, pkColumnname, valueColumnName and pkColumnValue when using TableGenerator to be on the safe side to monitor your IDs.

Relations

In this section I’ll not tell what the optional parameters are good for. I’ll just list them up alongside with the annotations and I provide the default values. Because the intention of this article is to provide a cheat sheet for annotations in the JPA.

Parameter / Annotation @OneToOne @OneToMany @ManyToOne @ManyToMany
cascade
fetch EAGER LAZY EAGER LAZY
optional true N/A true N/A
mappedBy N/A
orphanRemoval false false N/A N/A

Legend:

  • “-“: Defaults to nothing
  • “N/A”: option not available for this annotation

As you can see above there is no default cascading for any of the annotations. And the reason why I decided to create this table was the fetch parameter. I see sometimes collections in entities (e.g. Lists or Sets) which have a FetchType.LAZY and I think about why do they mention it. In the project we had a discussion if we should load the collections belonging to entities lazy or eager. (If you are not shure what the two do: eager loads everything with one database query and assembles the object tree even if won’t be used; lazy loads the collections only when accessed with a .get method of the entity – resulting in multiple queries to the database). It is always a performance issue where we should fetch eager or lazy but at the beginning of a project you cannot see which would be good.

Conclusion

This started as a simple cheat-sheet article on optional parameters of JPA2 annotations and I ended up with a big post — or at least big in my eyes where an article should have at least 500 words counted by WordPress. Nevertheless I hope that you find it useful too and if you have any questions feel free to ask and I hope I can give you the answer.

Advertisements

One thought on “Java Persistence Api Annotation Cheat Sheet

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s