JPA JPA2 - Eigene Klassen/Typen als Persistenzattribute, Best Practice

Wladimir

Mitglied
Ich habe in meinen Entities nicht nur primitive Typen oder deren Java-Wrapper sondern auch eigene Typen die primitive "wrappen". Entweder haben diese extra Funktionalität oder geben die Verwendung durch den Typ genauer an.

Beispiel:
Java:
@Entity
public class Square {
   private RGB color;
   ...
}

public class RGB implements Serializable{
   private int colorValue;
   public RGB(int red, int green, int blue)
   {	
	setRGBColor(red, green, blue);
   }
   ...
}
Auf einer klassischen relationalen Datenbank führt dies jedoch beim Lesen/Schreiben zu Exceptions, da der Typ für die Datenbank unbekannt ist.

Leider habe ich mit pur JPA2 nur eine Möglichkeit per Embeddable gefunden um diese Typen persistierbar zu machen.
Java:
@Entity
public class Square {
   @AttributeOverride(name="colorValue", column=@Column(name="SQUARE_COLOR"))
   public RGB getColor() {
      return this.color;
   }
   ...
}
@Embeddable
public class RGB implements Serializable{
	private int colorValue;
	...
}

Diese Lösung geht zwar gut, benötigt aber ein AttributeOverride wenn die Datenbankspalte nicht "colorValue" heißt.

Als 2te Möglichkeit bietet Eclipselink Converter an:
Java:
@Entity
public class Square {
	@Converter(converterClass=RGBConverter.class, name="RGBConverter")
	@Convert("RGBConverter")
	public RGB getColor() {
		return this.color;
	}
...
}

public class RGBConverter implements Converter{

	private static final long serialVersionUID = 1L;

	@Override
	public Object convertDataValueToObjectValue(Object dataValue, Session session) {
		RGB rgb = new RGB();
		rgb.setColorValue((int) dataValue);
		return rgb;
	}

	@Override
	public Object convertObjectValueToDataValue(Object objectValue, Session session) {
		return ((RGB)objectValue).getColorValue();
	}
	...
}

Das funktioniert auch gut, braucht aber eben pro Typ einen eigenen "Converter" und ist nicht pur JPA2.

Was meint ihr? Welche Variante ist sinnvoller, oder gibt sonst noch andere Möglichkeiten?
 
Die erste Variante ist die Bessere. Sie heißt Composite Identifier. Vergiss aber die Annotation
Code:
@Id
über
Code:
getColor()
nicht
 
Es geht hier nicht um einen zusammengesetzen Schlüssel. Vielleicht habe ich das im Beispiel nicht klar verdeutlicht.
Code:
Square.color
ist ein gewöhnliches Persistenzattribut. Aber trotzdem teilen wir die gleiche Meinung. Ziehe bei Embeddable vs Converter ebenfalls Embeddable vor falls möglich.
Als kleine Optimierung habe ich noch den Property/Field Namen in den zu überschreibenden Typen verschoben. Das macht die Sache besser "refactorable".
Java:
@Entity
public class Square {
   @AttributeOverride(name=RGB.ATTRIBUTE, column=@Column(name="SQUARE_COLOR"))
   public RGB getColor() {
      return this.color;
   }
   ...
}
 

Neue Themen


Zurück
Oben