Hallo allerseits
Ich habe das Problem beim Speichern eines komplexen Objekts, wenn ein Teil-Objekt aus der Db geholt wird, da zuvor schon gespeichert.
Folgendes (vereinfachtes) Beispiel:
Die Klasse Anrede:
Klasse Kunde:
Klasse Vertrag:
Wenn ich den Vertrag erzeuge, wobei auch ein neuer Kunde erstellt wird (also nicht aus der Db geholt), funktioniert das Speichern problemlos. Wenn ich aber für den Vertrag einen bestehenden Kunden haben möchte, funktioniert es nicht:
In ter Tabelle Anrede existiert ein Eintrag mit PK 13: dies gehört dem Kunde-Objekt, das ich aus der Db hole, um ihn mit dem Vertrag "zu verknüpfen".
Ich hätte erwartet, dass es erkannt wird, dass das Kunde-Objekt in der Db schon existiert (mit seiner Anrede) und demzufolge kein neuer Eintrag gemacht wird.
Was mache ich falsch hier? Muss ich jetzt noch das komplexe Objekt in einzelne Teile zerlegen und dann jeweil prüfen, ob das Objekt in der Db schon enthalten ist und je nach Resultat anders handeln? Macht das nicht der JPA-Provider selbst (Eclipse Link)? Oder, ist meine Beziehung falsch definiert?
Danke für jeden Tipp.
Ich habe das Problem beim Speichern eines komplexen Objekts, wenn ein Teil-Objekt aus der Db geholt wird, da zuvor schon gespeichert.
Folgendes (vereinfachtes) Beispiel:
Die Klasse Anrede:
Java:
@Entity
public class Anrede implements Serializabler {
@Id
@GeneratedValue
private int id;
private String bezeichnung;
Klasse Kunde:
Java:
public class Kunde implements Serializable{
@Id
@GeneratedValue
private int id;
@ManyToOne(cascade = CascadeType.ALL)
private Anrede anrede;
private String vorname;
private String nachname;
@OneToOne(cascade = CascadeType.ALL)
private Adresse adresse;
@OneToMany(mappedBy = "kunde", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private final List<Vertrag> vertragListe = new ArrayList<Vertrag>();
// ...
}
Klasse Vertrag:
Java:
@Entity
@Cacheable(false)
public class Vertrag implements Serializable{
@Id
@GeneratedValue
private int id;
@ManyToOne(cascade = CascadeType.ALL)
private Kunde kunde;
// ...
}
Wenn ich den Vertrag erzeuge, wobei auch ein neuer Kunde erstellt wird (also nicht aus der Db geholt), funktioniert das Speichern problemlos. Wenn ich aber für den Vertrag einen bestehenden Kunden haben möchte, funktioniert es nicht:
Java:
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint »anrede_pkey«
Detail: Schlüssel »(id)=(13)« existiert bereits.
Error Code: 0
Call: INSERT INTO ANREDE (ID, BEZEICHNUNG) VALUES (?, ?)
bind => [2 parameters bound]
Query: InsertObjectQuery(Anrede [id=13, bezeichnung=Herr])
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
... (stacktrace)
In ter Tabelle Anrede existiert ein Eintrag mit PK 13: dies gehört dem Kunde-Objekt, das ich aus der Db hole, um ihn mit dem Vertrag "zu verknüpfen".
Ich hätte erwartet, dass es erkannt wird, dass das Kunde-Objekt in der Db schon existiert (mit seiner Anrede) und demzufolge kein neuer Eintrag gemacht wird.
Was mache ich falsch hier? Muss ich jetzt noch das komplexe Objekt in einzelne Teile zerlegen und dann jeweil prüfen, ob das Objekt in der Db schon enthalten ist und je nach Resultat anders handeln? Macht das nicht der JPA-Provider selbst (Eclipse Link)? Oder, ist meine Beziehung falsch definiert?
Danke für jeden Tipp.