1

I'm working on a Hibernate project, here is an extract of my class:

@Entity
@Table(name = "T_JOB")
@SequenceGenerator(name = "seqJob", sequenceName = "SEQ_JOB", allocationSize = 1)
@Getter
@Setter
public class Job {

    @Convert(converter = HibernateBooleenVersCaractere.class)
    @Column(name = "STATUT_EXTRACTION")
    private boolean statutExtraction;
}

In my database STATUT_EXTRACTION is a CHAR type that's why I used a converter (HibernateBooleenVersCaractere implements AttributeConverter) and it worked perfectly. The boolean statutExtraction was usefull until now because I had only two state (OK = true = 1 in DB, Error = false = 0 in DB). But now I would like to add a state. In order to do that I created a enum state and used enumerated type:

@Entity
@Table(name = "T_JOB")
@SequenceGenerator(name = "seqJob", sequenceName = "SEQ_JOB", allocationSize = 1)
@Getter
@Setter
public class Job {
    public enum Statut {
        ERROR, OK, LOAD
    }

    @Column(name = "STATUT_EXTRACTION")
    @Enumerated(EnumType.STRING)
    private Statut statutExtraction;
}

Here I got an error caused by EnumType different from STATUT_EXTRACTION type in database I guess.

I had a second idea: use a converter as I did for converting boolean to char:

public class HibernateEnumVersChar
        implements
        AttributeConverter<Statut, Character> {

    @Override
    public Character convertToDatabaseColumn(final Statut statut) {
        if (statut == Statut.OK) {
            return '1';
        } else if (statut == Statut.LOAD) {
            return '2';
        } else if (statut == Statut.ERROR) {
            return '0';
        } else {
            return null;
        }

    }

    @Override
    public Statut convertToEntityAttribute(final Character dbData) {
        if (dbData == '1') {
            return Statut.OK;
        } else if (dbData == '2') {
            return Statut.LOAD;
        } else if (dbData == '0') {
            return Statut.ERROR;
        } else {
            return null;
        }
    }

}

And changed my Job class to:

@Entity
@Table(name = "T_JOB")
@SequenceGenerator(name = "seqJob", sequenceName = "SEQ_JOB", allocationSize = 1)
@Getter
@Setter
public class Job {
    public enum Statut {
        ERROR, OK, LOAD
    }

    @Convert(converter = HibernateEnumVersChar.class)
    @Column(name = "STATUT_EXTRACTION")
    private Statut statutExtraction;
}

And here I have this error:

Error attempting to apply AttributeConverter

Sadly I can't change the database type (char) because I have a lot of data.

Has some one an idea where can my error be (or why not a different way to do what I need to do !) ?

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
C.Norris
  • 87
  • 1
  • 13

1 Answers1

1

What I suggest here is to use the @Enumerated annotation with the attribute EnumType.ORDINAL, ORDINAL here will get you a number 0, 1 or 2 giving the order the value was defined in the Enum.

So when you define:

public enum Statut {
    ERROR, OK, LOAD
}

So here we will have:

Statut.ERROR.ordinal()  ---> gives 0
Statut.OK.ordinal()  ---> gives 1
Statut.LOAD.ordinal()  ---> gives 2

Conculsion:

Change your column definition like this:

@Enumerated(EnumType.ORDINAL)
@Column(name = "STATUT_EXTRACTION")
private Statut statutExtraction;

Note:

The database column should be changed to NUMBER(1,0), or you can convert it to a Char inside your Enum definition, please read Hibernate & Enum handling article for further details.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • Damn thank you, I feel stupid, I thought EnumType.ORDINAL was for Enum with integers. – C.Norris Nov 07 '17 at 12:37
  • but this will really works ? Don't we need a NUMBER in DB when using EnumType.ORDINAL ? – C.Norris Nov 07 '17 at 12:48
  • @C.Norris You are welcome, gload it helps. Yes I forgot that, you need to map it as a `NUMBER(1,0)` in your DB, or use a converter again to convert it to a CHAR. – cнŝdk Nov 07 '17 at 13:06
  • Then I will have @Enumerated + @Convert(Number to char) ? Isn't it the same to use immediatly what I tried: @Convert(Statut to char ?) – C.Norris Nov 07 '17 at 13:14
  • 1
    @C.Norris Yes but the best would be to use `NUMBER`, it will be more performant in Reading/Writing operat1ions, but you can handle the conversion in your ENUM definition please check [**Hibernate & Enum handling**](http://javadata.blogspot.com/2011/07/hibernate-and-enum-handling.html). – cнŝdk Nov 07 '17 at 13:26