Um JSON mit JPA und dem Provider Eclipselink zu verwenden, sind folgende Schritte notwendig
- Erstellen eines Konverters
- Annotation der Attribute der Entität
- Annotation @Mutable von Eclipselink verwenden
In diesem Beispiel wollen wir eine Liste vom Typ AbstrachItem
serialisieren und deserialisierten.
Erstellen eines Konverters
Der Konverter sagt JPA, wie mit den Daten umzugehen ist. In diesem Fall soll JSON marshall / unmarshall aufgerufen werden. In dem vereinfachten Code sorgt ein JacksonHelper
dafür, dass mit dem ObjectMapper die Operationen durchgeführt werden.
@Converter(autoApply = true)
public class JsonItemActionListConverter implements AttributeConverter, String> {
...
@Override
public String convertToDatabaseColumn(List<AbstractItem> value) {
return JacksonHelper.marshallListToJSON(new
}
/**
* Konvertiert einen (aus der DB gelesenen) String in eine Liste von Aktionen
* @param value (json-)String der die Liste repräsentiert
* @return (mindestens leere) Liste der Aktionen
*/
@Override
public List<AbstractItemAction> convertToEntityAttribute(String value) {
return JacksonHelper.unmarshallListFromJSON(value, AbstractItemAction.class);
}
Annotation der Attribute der Entität
Der Konverter wird nun in der Entität verwendet.
/** Liste der auszuführenden Aktionen */
@Column(name = "actions_as_json", nullable = true, columnDefinition = "json")
@Convert(converter = JsonItemActionListConverter.class)
private List<AbstractItemAction> actionsAsJson = new ArrayList<>();
Wenn ihr nun versucht, Daten zu speichern, funktioniert dies initial. Eine Aktualisierung der Werte ist allerdings nicht möglich. Dies liegt daran, dass Eclipselink den Wert wegen des Konverters nicht als “mutable” einstuft. Um dies zu ändern, muss eine entsprechende Annotation ergänzt werden (es gibt auch noch andere Möglichkeiten).
/** Liste der auszuführenden Aktionen */
@Column(name = "actions_as_json", nullable = true, columnDefinition = "json")
@Convert(converter = JsonItemActionListConverter.class)
@Mutable
private List<AbstractItemAction> actionsAsJson = new ArrayList<>();
So definiert wird das gewollte erreicht.
Siehe auch: https://eclipse.dev/eclipselink/documentation/2.4/concepts/app_dev005.htm#CCHBBHDH