9

We are developing an application connected to a legacy database. This is very "untyped", using strings for almost all data. What is worse is that is far of being homogeneous: it uses different patterns for dates or times ('YYDDMM', 'HHMMSS', milliseconds) and booleans ('Y'/'N', 'X'/' '), for example.

We want to use JPA (EclipseLink) and custom converters. The problem is that @Convert expects a class implementing AttributeConverter, so we have to do new classes for each pattern. What I'd like is a BooleanConverter class, which can be instantiated with values 'Y'/'N' or 'X'/' '.

This is obviously out of JPA spec, but maybe it's possible using EclipseLink annotations/configuration. Looking at its @Convert annotation, a converter can be specified by name. This sounds good to me if I can register a ynBooleanConverter and xSpaceBooleanConverter:

// Unfortunately, this method does not exist :(
Session.addConverter('ynBooleanConverter', new BooleanConverter("Y", "N")); 

@Entity
public class MyEntity {

    @Convert("ynBooleanConverter")
    private Boolean myBoolean;

    ...
}

Is it possible? What other options do we have?

sinuhepop
  • 20,010
  • 17
  • 72
  • 107

3 Answers3

2

Try @ObjectTypeConverter:

@Entity
@ObjectTypeConverters({
    @ObjectTypeConverter(name = "ynBooleanConverter", objectType = Boolean.class, dataType = String.class, 
        conversionValues = { 
        @ConversionValue(objectValue = "true", dataValue = "Y"), 
        @ConversionValue(objectValue = "false", dataValue = "N") }),
    @ObjectTypeConverter(name = "xSpaceBooleanConverter", objectType = Boolean.class, dataType = String.class, 
        conversionValues = { 
        @ConversionValue(objectValue = "true", dataValue = "X"), 
        @ConversionValue(objectValue = "false", dataValue = " ") }),
})
public class MyEntity {

    @Convert("ynBooleanConverter")
    private boolean ynBoolean;

    @Convert("xSpaceBooleanConverter")
    private boolean xSpaceBoolean;
}
Ish
  • 3,992
  • 1
  • 17
  • 23
  • 1
    Thanks. This works only for Booleans, but not for dates with different formats. – sinuhepop Oct 08 '15 at 16:07
  • I guess you have to implement an annotation of your own to achieve that conversion. I doubt that there is support for that logic in either EclipseLink or JPA. – Ish Oct 08 '15 at 17:27
0

So your Converter behaves different depending on some state in the context? I think I would try to bind the context info to a threadlocal variable which I can read back in the Converter implementation.

Do you have access to a CDI-implementation? Then its even more elegant to inject some bean with your context info into your Converter-implementation. You mentioned that you are missing some session-Methods? Maybe a @SessionScope'ed bean will help you.

Sadly @Inject is not specified in a converter class. You will need to lookup the bean "by hand" like mentioned in this post.

Community
  • 1
  • 1
frifle
  • 810
  • 5
  • 24
  • Converters don't behave depending on the state, but the actual field which are converting. I have several different patterns for dates saved using strings. I don't want to create so many classes, but only one. – sinuhepop Oct 26 '15 at 17:52
0

Too late to this thread, but here is a blog post which shows how JPA converters are to be written. Has working code for String and LocalDate conversions.

sunitkatkar
  • 1,958
  • 1
  • 14
  • 12