Ich habe zwei Entitäten:Persistierende @OneToMany Beziehungen mit @JoinColumn und @MapKeyColumn
@Entity
Article {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name="embed_id", referencedColumnName="id")
@MapKeyColumn(name = "language")
@MapKeyEnumerated(EnumType.ORDINAL)
private Map<Language, Locale> locales;
Article() {
locales.put(Language.CS, new Locale());
locales.put(Language.EN, new Locale());
}
}
@Entity
Locale {
@Id
private Long embed_id;
@Id
private Language language;
@Column(length = 256)
private String name;
}
Dank Konstruktor kann ich sicherstellen, dass, sobald ein Article
instanziert wird, zwei Locales
(mit CascadeType.ALL) sind damit verbunden.
Das Problem kommt, wenn ich versuche, eine solche Einheit bestehen bleiben - ich erhalte:
javax.persistence.EntityExistsException:
a different object with the same identifier value was already associated
with the session: org...Locale#[email protected]
Das Problem ist, dass weder embed_id
haben noch language
Werte aus dem Artikel zugewiesen, wenn persistierende und Hibernate sie nicht assoziieren nach beharrlicher Artikel. Wie kann das gemacht werden?
Edit 1:
Ich habe, dass, wenn die embed_id
und language
manuell eingestellt werden, alles richtig funktioniert. Ich muss nur Hibernate sagen, um den Wert von @JoinColumn
und @MapKeyColumn
gemäß der @OneToMany
Beziehung zu setzen.
Edit 2:
Das Problem mit MapKeyColumn hat eine einfache Lösung:
public void addLocale(Language l, Locale locale) {
locale.setLanguage(l);
this.locales.put(l);
}
Aber ich bin nach wie vor nicht in der Lage, die Locale.embed_id von Article.id zu sagen, überwintern zu verknüpfen.
bearbeiten 3:
Ich kann sehen, dass die ID des Artikels richtig erzeugt wird, aber dann ist es nicht in den Lokalisierungs setzen:
DEBUG org.hibernate.event.internal.AbstractSaveEventListener -
Generated identifier: 87, using strategy: org.hibernate.id.SequenceGenerator
DEBUG org.hibernate.event.internal.AbstractSaveEventListener -
Generated identifier: component[language,embedId]{language=0, embedId=null}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
DEBUG org.hibernate.event.internal.AbstractSaveEventListener -
Generated identifier: component[language,embedId]{language=1, embedId=null}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
Ich weiß, aber wie kann ich Hibernate mitteilen, sie mit dem Schlüssel der Karte zu verknüpfen? Es ist nicht nur Sprache - denn wenn ich es manuell setze, bekomme ich: 'Nullwert in Spalte" embed_id "verletzt Nicht-Null-Einschränkung;' –
Aber 'embed_id' ist nicht unbedingt einzigartig (weil Sie es mit' Sprache' kombinieren um Einzigartigkeit zu erreichen). Wahrscheinlich kann ein nicht eindeutiger Schlüssel nicht der (eindeutige) Schlüssel einer Map sein? –
Es ist einzigartig in Kombination mit Sprache. Der Primärschlüssel ist die Kombination "embed_id, language". –