This tutorial shows you how to map an enum type from Java to a column in database with Hibernate ORM framework. It’s very common that a database column stores enumerated values such as gender (male or female), status (new, in progress, closed), etc. Hibernate makes that easy to implement. Let’s see the basic elements are used for enum type mapping, in both annotation and XML.

Suppose that we have a database table called person which can be created by executing the following MySQL script:

CREATE TABLE `person` (
  `person_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `gender` int(4) NOT NULL,
  PRIMARY KEY (`person_id`)
)
Here, the column gender can hold value in a specified range (enumeration), e.g. 0 for male and 1 for female.

In Java side, we have a model class called Person as shown below:

public class Person {
	private int id;
	private String name;
	private Gender gender;

	// getters and setters...
}
Here, the gender attribute is an enumeration type, which is declared as below:

public enum Gender {
	MALE, FEMALE
}
Now, we want to map this enumeration type to the column gender in the database. Let’s see how to do that in Hibernate.

 

1. Using @Enumerated Annotation

We can use the JPA’s @Enumerated annotation to annotate the getter method of the gender attribute as follows:

@Enumerated(EnumType.ORDINAL)
public Gender getGender() {
	return gender;
}
If the database column is of type number (integer), we should use the EnumType.ORDINAL parameter which tells Hibernate to insert values according to order of the enum constant. For example, if the MALE is the first constant then 0 will be inserted; if the FEMALE is the second then 1 will be inserted, and so on.



In case the database column is of type character (varchar), the EnumType.STRING should be used. For example:

@Enumerated(EnumType.STRING)
public Gender getGender() {
	return gender;
}
Then Hibernate will insert name of the enum constant, e.g. MALE and FEMALE to the database.

 

2. Using XML Mapping

In case XML mapping is used instead of annotations, declare mapping for the gender column as following:

<property name="gender" column="GENDER">
	<type name="org.hibernate.type.EnumType">
		<param name="enumClass">net.codejava.hibernate.Gender</param>
	</type>
</property>
That’s equivalent to usage of the EnumType.ORDINAL parameter with annotations.

The following XML mapping snippet is equivalent to usage of the EnumType.STRING parameter:

<property name="gender" column="GENDER">
	<type name="org.hibernate.type.EnumType">
		<param name="enumClass">net.codejava.hibernate.Gender</param>
		<param name="useNamed">true</param>
	</type>
</property>
Note that, some document says <param name="type">12</param> for mapping to a varchar column. However, using the useNamed attribute is much more descriptive.

 

3. Annotating Model Class

The following snippet is code of the Person class which is annotated using JPA annotations:

package net.codejava.hibernate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name = "PERSON")
public class Person {
	private int id;
	private String name;
	private Gender gender;

	public Person(String name, Gender gender) {
		this.name = name;
		this.gender = gender;
	}

	@Id
	@Column(name = "PERSON_ID")
	@GeneratedValue
	public int getId() {
		return id;
	}

	@Enumerated(EnumType.ORDINAL)
	public Gender getGender() {
		return gender;
	}

	// other getters and setters
}
Here, code of other getters and setters are removed for brevity.

 

4. Writing Test Class

Below is code of a console program that tries to save two persons (male and female) to the database.

package net.codejava.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateTest {

	public static void main(String[] args) {
		// loads configuration and mappings
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry
			= new StandardServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).build();
		
		// builds a session factory from the service registry
		SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		
		// obtains the session
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		
		Person malePerson = new Person("Tom", Gender.MALE);
		session.save(malePerson);
		
		Person femalePerson = new Person("Mary", Gender.FEMALE);
		session.save(femalePerson);
		
		session.getTransaction().commit();
		session.close();
		
		StandardServiceRegistryBuilder.destroy(serviceRegistry);
		
	}

}
The result can be seen using MySQL console as in the following screenshot:

hibernate enum type mapping test result

 Watch the video below to see how to maping enum type in Hibernate in action:

 

Other Hibernate Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (HibernateEnumMappingExample.zip)HibernateEnumMappingExample.zip[Eclipse-Maven Project]15 kB

Add comment

   


Comments 

#3Reuben2015-12-16 15:45
<param name="useNamed">true</param>
is more elegant. But to make this map properly to a varchar column in the database (on Oracle 11g), I also needed to add
<param name="type">12</param>
Quote
#2Reuben2015-12-16 15:39
I agree that
true
is more elegant. But to make this map properly to a varchar column in the database, I also needed to add
12
Quote
#1Dan Toomey2015-11-18 02:38
This is not the correct use of enum in mysql - mysql has a column type enum.
Quote