Coffee Talk: Java, News, Stories and Opinions

Jun 13 2018   9:20PM GMT

JPA and Hibernate enum mapping with annotations and the hbm.xml file

cameronmcnz Cameron McKenzie Profile: cameronmcnz

Tags:

Just how hard is it to perform a JPA or Hibernate enum mapping with either annotations or a hbm.xml file? It’s actually not that hard at all. In fact, you don’t necessarily have to perform any mappings because the Hibernate defaults will take care of most of the low-level details for you.

JPA and Hibernate enum mapping

The Java enum, introduced in Java 5, will map to the underlying database without any intervention. The JPA framework, be it Hibernate or Toplink or DataNucleus, will recognize the Java enum and subsequently read or write the enums state to and fro. So it doesn’t require any additional annotations or coding in a hbm.xml file.

Whenever I need to prove out a concept, I always like to code up a little rock-paper-scissors program. In this use case, we can represent a competitor’s chosen gesture in the game as a Java enum:

package com.mcnz.rps;
public enum Gesture {
   ROCK, PAPER, SCISSORS;
}

Working with persistent entities

So long as any persistent object in the problem domain is decorated with the requisite @Entity and @Id attributes, the Java enum database mapping will proceed without error. The following is a JPA annotated entity that uses the Java enum named Gesture:

/* JPA & Hibernate enum mapping example */	 
package com.mcnz.rps;
import javax.persistence.*;

@Entity
public class GameSummary {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long id;
	private Gesture clientGesture;
	private Gesture serverGesture;
	private String result;
	private java.util.Date date = new java.util.Date();
	
	public GameSummary(){}
	public GameSummary(Gesture clientGesture, Gesture serverGesture) {
		super();
		this.clientGesture = clientGesture;
		this.serverGesture = serverGesture;
	}
}
/* End of Hibernate and JPA enum mapping example */	

JPA and Java enum persistence

Now that we’ve created the Java enum and coded the JPA or Hibernate entity, all we need to do is give the JPA EntityManager or the Hibernate Session some attention and database persistence should be a lead-pipe cinch.

/* Entity that has a JPA/Hiberante mapped enum */
GameSummary gs = new GameSummary();
gs.clientGesture = Gesture.PAPER;
gs.serverGesture = Gesture.ROCK;
gs.result = "win";

/* Persisting the JPA/Hiberate mapped enum */		
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-enum-mapping");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(gs);
em.getTransaction().commit();

Java enums and the EnumType annotation

There is, however, a last-minute surprise with this Hibernate enum mapping approach. The ordinal number of the Java enum is written to the database, as opposed to an actual String. So the ROCK gesture is persisted as 0 and the PAPER gesture is persisted as 1.

Ordinal values appear with a default JPA or Hibernate enum mapping

Default JPA Hibernate enum mapping writes ordinal values to the database.

To get the JPA or Hibernate enum mapping process to write text to the database instead of an ordinal number, the trick is to use the @Enumerated annotation in conjunction with @EnumType.

@Enumerated(EnumType.STRING)
private Gesture clientGesture;
@Enumerated(EnumType.STRING)
private Gesture serverGesture;
Using EnumType annotation to force JPA and Hibernate enum mapping to write a text String to the database.

Using EnumType String to persist text instead of Java enum ordinal numbers.

Mapping with @Enumerated and @EnumType annotations

With the EnumType set to STRING as opposed to ORDINAL, the JPA and Hibernate enum mapping represents the Java enum with specific text instead of the enum’s ordinal value.

Of course, all of these mappings have used JPA. The concepts all map directly to Hibernate, although the syntax is slightly different, especially if you use a hbm.xml file for enum mapping. The XML would look as follows:

<property name="gesture" column="GESTURE">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">com.mcnz.rps.Gesture</param>
<param name="useNamed">true</param>
</type>
</property>

And without the useName parameter — or if the useName parameter is set to false — an ordinal value representing the enum is used, otherwise the String representation of the enum is persisted to the database.

And that’s it. Those are the ins and outs of using Hibernate and JPA enum mapping facilities.

Hibernate and JPA enum mapping meme - enum num num.

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: