Map postgreSQL enum for Java enumeration with JPA (EclipseLink) and custom converter
I am trying to map from JPA ( EclipseLink
provider) postgreSQL ENUM
type to Java enum type (and vice versa).
I know I can easily map a Java enum to a type varchar
in my annotated postgreSQL database @Enumerated
, but I want to map it in the postgreSQL tgp ENUM
. I think I have to use the native EclipseLink converter for this.
So, I started to implement org.eclipse.persistence.mappings.converters.Converter
but don't know how to implement the methods convertObjectValueToDataValue
, initialize
and isMutable
...
Can someone explain to me how to implement these methods?
Now my class is as follows:
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 the explanations, I searched for custom converters for EclipseLink with Google, but this time Google was not my friend.
source to share
Ok, I ran some tests with a basic SELECT statement in another project and I saw that my postgreSQL type is ENUM
returned PGObject
with both the value set to my ENUM
(in my case FR
, EN
or DE
) and the type of my enum name.
Example: if I create the following ENUM
in pg:
CREATE TYPE langage AS ENUM ('FR', 'EN', 'DE');
I will get PGObject
with value FR
or EN
or DE
and with type langage
.
So, when I want to convert a Java object to mine ENUM
, I just create a custom EclipseLink Converter
and return it PGObject
like this in 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 works great.
Hope it helps.
source to share