2015-10-07 3 views
8

Wir entwickeln eine Anwendung, die mit einer Legacy-Datenbank verbunden ist. Dies ist sehr "untypisiert" und verwendet Strings für fast alle Daten. Was noch schlimmer ist, ist, dass es weit davon entfernt ist, homogen zu sein: Es verwendet verschiedene Muster für Daten oder Zeiten ('YYDDMM', 'HHMMSS', Millisekunden) und boolesche ('Y'/'N', 'X'/''), z Beispiel.JPA: Parametrisierte Instanzen von AttributeConverter

Wir wollen JPA (EclipseLink) und benutzerdefinierte Konverter verwenden. Das Problem ist, dass @Convert eine Klasse erwartet, die AttributeConverter implementiert, also müssen wir neue Klassen für jedes Muster machen. Was ich möchte, ist eine BooleanConverter-Klasse, die mit Werten 'Y'/'N' oder 'X'/'' instanziiert werden kann.

Dies ist offensichtlich außerhalb der JPA-Spezifikation, aber vielleicht ist es möglich, EclipseLink Annotationen/Konfiguration zu verwenden. Mit der Anmerkung @Convert kann ein Konverter namentlich angegeben werden. Das klingt gut für mich, wenn ich einen ynBooleanConverter und xSpaceBooleanConverter registrieren:

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

@Entity 
public class MyEntity { 

    @Convert("ynBooleanConverter") 
    private Boolean myBoolean; 

    ... 
} 

Ist es möglich? Welche anderen Möglichkeiten haben wir?

+0

ist es für Sie geeignet JPA 2.1 Konverter zu verwenden? verfügbar ab Eclipselink Version 2.5? –

+0

Ich kann die letzte Version von EclipseLink verwenden, aber ich kann nicht sehen, wie ich es lösen kann. – sinuhepop

Antwort

1

Versuchen @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; 
} 
+0

Danke. Dies funktioniert nur für Boolesche Werte, nicht jedoch für Datumsangaben mit unterschiedlichen Formaten. – sinuhepop

+0

Ich denke, Sie müssen eine eigene Anmerkung implementieren, um diese Konvertierung zu erreichen. Ich bezweifle, dass diese Logik in EclipseLink oder JPA unterstützt wird. – Ish

0

Also Ihr Converter auf einem gewissen Zustand abhängig verschiedene verhält im Kontext? Ich denke, ich würde versuchen, die Kontextinformation an eine threadlokale Variable zu binden, die ich in der Konverterimplementierung zurücklesen kann.

Haben Sie Zugriff auf eine CDI-Implementierung? Dann ist es noch eleganter, etwas Bohne mit Ihrer Kontextinfo in Ihre Converter-Implementierung zu injizieren. Sie haben erwähnt, dass Ihnen einige session -Methoden fehlen? Vielleicht hilft Ihnen eine @SessionScope Ed-Bohne.

Traurig @Inject ist in einer Konverterklasse nicht angegeben. Sie müssen die Bohne "von Hand" nachschlagen, wie in this Post erwähnt.

+0

Konverter verhalten sich nicht abhängig vom Status, sondern vom tatsächlichen Feld, das konvertiert wird. Ich habe verschiedene Muster für Daten, die mit Strings gespeichert wurden. Ich möchte nicht so viele Klassen erstellen, sondern nur einen. – sinuhepop