JPA Optionales single value embeddable mit nonnull-field

Gegeben sei eine Entity:

public class MyEntity {
    @Id private Integer id;
    private MyEmbeddable myEmb;
}```
und eine Klasse, die embeddable ist
```@Embeddable
public class MyEmbeddable {
    private int singleValue;
}```

In MyEntity soll das Feld myEmb null sein können. Hibernate erkennt aber nicht, dass myEmb nullable ist, sondern legt die Spalte in der Datenbank nonnull an (weil ja MyEmbeddable.singleValue ein primitiver Typ ist).

Wie bringe ich Hibernate bei, dass MyEntity.myEmb auch null sein darf?

Embeddable haben normalerweise mehrere Attribute, dazu gehören dann mehrere Spalten. Hibernate betrachtet ein Embeddable als NULL, wenn alle Attribute NULL sind - aber das geht ja bei dir nicht.

Schon mal Single als Typ und @Column(nullable = true) versucht?

Ok, eine Suche nach „jpa embedded entity null“ brachte folgendes zutage:
http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Nulls

Im embeddable muss man also „nur“ den primitiven Datentyp durch den Wrapper austauschen und dann funktioniert es. Dabei darf die zugehörige Column nicht als nullable = false annotiert sein…

*** Edit ***

Das funktioniert, danke. Wobei ich natürlich Integer als Typ genommen habe. Die Bezeichnung „singleValue“ war vielleicht ein bisschen irreführend :wink:
Die Column-Annotation kann man sich dabei komplett sparen, weil nullable = true der Defaultwert ist.
Schade, dass man das nicht anders modellieren kann.

Nebenfrage: warum brauchst du eine embedded Entity mit nur einem Attribut? Ist das wirklich sinnvoll??

Ja, das ist sinnvoll. Die Entity ist nämlich nicht dumm, sondern enthält außer den Daten noch weitere Logik. In diesem Fall geht es konkret um eine “Entity” (im DDD-Sinne ist das eher ein Value-Object, daher auch embedded), die eine Netzwerkadresse repräsentiert. Es wäre etwas unhandlich im Container der Netzwerkadresse mit einem einfachen Integer zu arbeiten - die Logik gehört in das Objekt.

Schon klar, ist in dem Fall wahrscheinlich eine gute Lösung.

Von der Logik her konnte ich mit solchen embedded Entities nie was anfangen - hab das auch noch nie verwendet. Normalerweise ist sowas doch eigentlich ein Zeichen für ein Ding, das besser in einer eigenen Tabelle aufgehoben und per Fremdschlüssel angesprochen würde. Aber schon klar, immer macht man das nicht und dann hat man halt solche 1:1 Beziehungen “innerhalb” einer Tabelle.

Ehrlich gesagt nutze ich embedded Entities ziemlich häufig. Das kommt aber daher, dass ich versuche domänengetrieben zu entwickeln.

Value-Objects haben keine Identität. Sie werden nur durch ihren Wert bestimmt (daher auch Value-Object) und sind immutable. Beispiele dafür sind IP-Adressen, Daten, eine Temperatur oder Geldeinheiten in Form eines Money-Objektes. Durch sie wird mehr der Zustand von etwas ausgedrückt als ein spezielles Verhalten.
Wenn ein Value-Object geändert werden muss, wird es ausgetauscht.

Genau dieses Verhalten hat man, wenn man ein Embeddable benutzt, abgesehen davon, dass die Objekte nicht echt immutable sein können und einen parameterlosen Konstruktor haben. Man würde Integer-Objekte oder Strings ja auch nicht in einer separaten Tabelle speichern und über eine Pseudo-ID referenzieren.