# JPA: update von Schlüsselwerten



## susanne_j (8. Apr 2014)

Hallo Forengemeinde,

ich habe ein kleines Problem und hoffe, das ihr mir doch vielleicht ein wenig Hilfestellung geben könnt.
(In Benutzung in dem Projekt ist Eclipselink, falls das noch wichtig ist.)

Gegeben ist eine Tabelle, die eine laufende Nummer als Teilschlüssel enthält. Ungefähr so:

```
@Entity

@Table(name="VT_VERTR_ANLAGEN")
@IdClass(VtAnlagePK.class)
class VtAnlage implements Serializable {
	
	@Id
	@ManyToOne
	@JoinColumn(name="vtr_id", nullable=false)
	VtVertragsKopf vertrag;
	
	@Id
	@Column(name="vtr_anl_lfd", precision=2, nullable=false)
	int lfdNr;
	
	@Column(name="vtr_anlage", length=125, nullable=false)
	String anlage;

	@Version
	@Column(name="OPTLOCK")
	int optlock;
}
```

Die Tabelle enthält also eine Vertrags-id und eine laufende Nummer, die beide zum Schlüssel gehören.
Die laufende Nummer soll auch lückenlos pro Vertrag, jeweils von 1 angefangen, vergeben werden.

Wenn ich nun dem Benutzer in meinem Java-Programm die Möglichkeit biete, dort Sätze zu löschen, wieder hinzuzufügen etc. habe ich hinterher ein fröhliches Durcheinander an meiner laufenden Nummer, da ich einen neuen Satz nicht mit einer - in der aktuellen Transaktion - gelöschten lfdNr erzeugen kann, oder wenn ein Satz gelöscht wird entsteht ja auch eine Lücke.

Vor dem Persist kann ich die laufende Nummer auch nicht neu vergeben / neu durchnummerieren, da dann ggfs. ein Fehler kommt, das der Satz zwischenzeitlich geändert wurde (aufgrund des @VERSION Feldes). (Und in JPA ist ja auch der komplette Schlüssel eine Identifikation des Datensatzes und bei einem merge schlägt es dann fehl...)

Hat jemand vielleicht eine Idee, wie ich die Datensätze in dieser Tabelle irgendwie wieder korrekt (so wie es meine Vorgabe ist) durchnummeriert bekomme?

Ich habe schon an ein transientes Feld gedacht, in dem ich die zukünftige lfdNr als orderId hinterlege aber wie bekomme ich die ggfs. im PostPersist dann in die Tabelle.
Im Moment sehe ich dan keine vernünftige Lösung, hoffentlich könnt Ihr mir da ein wenig weiterhelfen...

Vielen Dank im Voraus,
Susi.


----------



## Barista (15. Apr 2014)

Dein Ansatz unterläuft die Logik von Schlüsseln.

Aber Du könntest alle entsprechenden Daten in einer anderen Struktur zwischenspeichern,
alle betroffenen Datensätze löschen und wieder einfügen.

Falls da noch andere daten dranhängen, geht das natürlich schief.

Also besser eine technische ID (UUID oder so) vergeben, die lebenslang zum Datensatz gehört.


----------



## susanne_j (16. Apr 2014)

Hallo Barista,

Vielen Dank für Deine Antwort!

Für das DB-Design bin ich leider nicht verantwortlich, habe aber inzwischen zugestanden bekommen, das eine "Sort-ID" eingefügt wird, die nicht im Schlüssel vorhanden ist und die Funktionalität der bisherigen laufenden Nummer hat.

Die laufende Nummer darf nun lückenhaft vergeben werden.

Insofern ist mein Problem behoben, ich kann die Sort-ID nun auch ändern/updaten.

Die Lösung, die ich noch im Kopf hatte war die, das bei der Löschung eines Datensatzes der Inhalt des Satzes mit der nächst höheren "laufenden-Nummer" in den Datensatz mit dem Schlüssel kopiert wird, der gelöscht werden sollte und damit der Datensatz mit dem höchsten Schlüssel gelöscht würde.

Das hätte aber zu blödsinningen Journal-Sätzen geführt (wir machen ein Journaling mit onUpdate und onDelete Triggern) und schlußendlich wurde mir dann eine Sort-ID genehmigt.

... mit reinem SQL war die Anforderung ja umsetzbar, worauf man mich auch immer wieder gerne hingewiesen hat ... ;(

Vielen Dank noch einmal!
Susi.


----------

