Olivier J.
Olivier J.

Reputation: 3175

Map postgreSQL enum to Java enum with JPA (EclipseLink) and custom converter

I'm trying to map with JPA (EclipseLink provider) a postgreSQL ENUM type to Java enum type (and vice versa).

I know I can easily map a Java enum to a varchar type in my postgreSQL database with the @Enumerated annotation but I want to map it in a postgreSQLENUM tpye. I think I must use a custom EclipseLink converter to do this.

So, I started to implement a org.eclipse.persistence.mappings.converters.Converter but I don't kown how to implement the convertObjectValueToDataValue, the initialize and the isMutable methods...

Can someone explain me how to implement these methods please ?

For now, my class is this one :

public class EnumConverter implements Converter {

private static final long serialVersionUID = 1L;

public Object convertDataValueToObjectValue(Object object, Session session) {

    if(object instanceof PGobject){
        return LangageEnum.valueOf(LangageEnum.class, ((PGobject)object).getValue());           
    }

    return null;
}

public Object convertObjectValueToDataValue(Object object, Session session) {
    // WHAT HERE...?
    // I tried to play with PGObject witout success...
    return object;
}

public void initialize(DatabaseMapping arg0, Session arg1) {
    // WHAT INITIALIZATION HERE...?
}

public boolean isMutable() {
    // TRUE OR FALSE AND WHY...?
    return false;
}

}

@Converter(name="langageConverter", converterClass=EnumConverter.class)
@Convert(value="langageConverter")
private LangageEnum langage;

Thanks for explanations, I searched for custom converters for EclipseLink with Google but this time Google was not my friend.

Upvotes: 3

Views: 2344

Answers (1)

Olivier J.
Olivier J.

Reputation: 3175

Ok, I made some test with basic SELECT statement in another project and I saw that my postgreSQL ENUM type is returned as PGObject with value set to the value of my ENUM (in my case FR, EN or DE) and with type of the name of my enum.

Ex : if I create the following ENUM in pg :

CREATE TYPE langage AS ENUM ('FR', 'EN', 'DE');

I will receive PGObject with value FR or EN or DE and with type langage.

So, when I want to convert Java object to my ENUM, I simply create a custom EclipseLink Converter and return a PGObject like this in the convertObjectValueToDataValue :

public class EnumConverter implements Converter {

private static final long serialVersionUID = 1L;

private static Logger logger = Logger.getLogger(EnumConverter.class);

public Object convertDataValueToObjectValue(Object object, Session session) {

    if(object instanceof PGobject){
        return LangageEnum.valueOf(LangageEnum.class, ((PGobject)object).getValue());           
    }

    return null;
}

public Object convertObjectValueToDataValue(Object object, Session session) {

    if(object instanceof LangageEnum){

        PGobject pg = new PGobject();

        try {
            pg.setValue(((LangageEnum)object).name());
            pg.setType("langage");
        } catch (SQLException e) {
            logger.log(Level.FATAL, e);
        }

        return pg;
    }

    return object;
}

public void initialize(DatabaseMapping dm, Session session) {
    dm.getField().setSqlType(Types.OTHER);
}

public boolean isMutable() {
    return true;
}

}

and it's work great.

Hope this helps.

Upvotes: 3

Related Questions