简体   繁体   中英

JPA: Parameterized instances of AttributeConverter

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?

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;
}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM