Mapping Java enum on Postgres enum with EclipseLink
eclipselink, jpa, postgresql
Solution
Why do you use a `@ObjectTypeConverter`, you can map Enumerations out of the box with eclipse link as shown here. `@Enumerated` is part of JSR-220 whereas `@ObjectTypeConverter` is a proprietary extension from EclipseLink JPA Extensions.
@Enumerated(EnumType.STRING)
@Column(name = "mood")
private Mood mood;
Problem
I am making first attempts with JPA (EclipseLink implementation) and feel quite stuck: In PostgreSQL I have the following db schema ``` CREATE TYPE mood AS ENUM ( 'sad', 'happy', 'enthusiastic' ); CREATE TABLE person ( pk BIGINT PRIMARY KEY, name VARCHAR NOT NULL, mood mood NOT NULL ); CREATE SEQUENCE person_pk_seq INCREMENT BY 100 MINVALUE 100; ``` Which works pretty fine, as this insert shows `INSERT INTO PERSON (PK, mood, name) VALUES (3, 'happy', 'Joe')` (Committing the pk as String makes no difference.) On the JPA side I wrote the following class: ``` package testdb; import java.io.Serializable; import javax.persistence.*; import org.eclipse.persistence.annotations.*; @Entity public class Person implements Serializable { private static final long serialVersionUID = 1L; public enum Mood { sad, happy, enthusiastic; } @Id @SequenceGenerator( name="PERSON_PK_GENERATOR", sequenceName="PERSON_PK_SEQ", allocationSize = 100 ) @GeneratedValue( strategy=GenerationType.SEQUENCE, generator="PERSON_PK_GENERATOR" ) public Long pk; @Enumerated( EnumType.STRING ) @Column( name = "mood" ) @ObjectTypeConverter( name = "moodConverter", objectType = Mood.class, dataType = String.class, conversionValues = { @ConversionValue( objectValue = "sad", dataValue = "sad" ), @ConversionValue( objectValue = "happy", dataValue = "happy" ), @ConversionValue( objectValue = "enthusiastic", dataValue = "enthusiastic" ) }) @Convert( "moodConverter" ) public Mood mood; @Column( name = "name" ) public String name; public static void main(String[] args) { EntityManagerFactory factory = Persistence.createEntityManagerFactory("TestDb.jpa.tests" ); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Person p = new Person(); em.persist( p ); System.out.println(p.pk); p.name = "Joe"; p.mood = Mood.enthusiastic; em.getTransaction().commit(); Query q = em.createQuery( "select p from Person p" ); Person x = (Person)q.getResultList().get(0); System.out.println( x.pk + " :: " +x.mood ); em.close(); } } ``` However, this example is not working and I have no clue what the problem is: ``` [EL Warning]: 2012-06-05 15:28:20.646--UnitOfWork(845463623)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.BatchUpdateException: Batch-Eintrag 0 INSERT INTO PERSON (PK, mood, name) VALUES ('801', 'enthusiastic', 'Joe') wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren. Error Code: 0 Call: INSERT INTO PERSON (PK, mood, name) VALUES (?, ?, ?) bind => [3 parameters bound] ``` When I alter the column type of table `person` to `varchar` and remove the annotations `@Convert` and `@ObjectTypeConverter` everything is working as expected, as well. Any ideas?