Blog
JPA-Implementierungsmuster: Verwendung von UUIDs als Primärschlüssel

In Fortsetzung der Blogserie von Vincent Partington über JPA-Implementierungsmuster möchte ich Folgendes hinzufügen Der Standardweg in JPA für Primärschlüssel ist die Verwendung der @GeneratedValue-Annotation mit dem Attribut strategy, das auf eine der Optionen AUTO, IDENTITY, SEQUENCE oder TABLE eingestellt ist. Sie wählen die für Ihre Situation am besten geeignete Strategie und das war's. Sie können den Primärschlüssel aber auch selbst generieren.
Die Verwendung von UUIDs für diese Zwecke ist ideal und hat einige große Vorteile. In unserem aktuellen Projekt haben wir diese Strategie angewandt, indem wir eine abstrakte Basisklasse erstellt haben, von der unsere Entitäten erben und die sich um den Umgang mit Primärschlüsseln kümmert.
@MappedSuperclass
public abstract class AbstractBaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
public AbstractBaseEntity() {
this.id = UUID.randomUUID().toString();
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
true zurückgeben;
if (obj == null)
return false;
if (!(obj instanceof AbstractBaseEntity)) {
return false;
}
AbstractBaseEntity other = (AbstractBaseEntity) obj;
return getId().equals(andere.getId());
}
}
Die Verwendung von UUIDs im Vergleich zu Sequenzen im Allgemeinen wurde im Internet bereits ausführlich diskutiert, so dass ich hier nicht zu sehr ins Detail gehen werde. Aber hier sind einige Pro- und Kontra-Argumente:
Profis
- Schreiben Sie diese Basisklasse einmal und jede Entität erhält eine Id gratis. Wenn Sie equals und hashcode wie oben implementieren, erhalten Sie auch diese als Bonus.
- UUID sind Universal Unique (was in einem Namen steckt). Das bedeutet, dass Sie sehr flexibel sind, wenn Sie Datensätze von Ort a nach Ort b kopieren/zusammenführen müssen, ohne dass Sie die Schlüssel neu generieren müssen. (oder komplexe Sequenzstrategien verwenden).
- UUIDs sind nicht zu erraten. Das bedeutet, dass es sicherer sein kann, sie der Außenwelt, z.B. in URLs, zugänglich zu machen. Ob dies eine gute Praxis ist, steht auf einem anderen Blatt.
Nachteile
- Die Leistung kann ein Problem sein. Siehe https://johannburkard.de/blog/programming/java/Java-UUID-generators-compared.html, Einige Datenbanken arbeiten nicht gut mit UUIDs (zumindest wenn sie als Strings gespeichert sind) für Indizes.
- Ordnen, Sortieren. Spricht für sich selbst.
- JPA-spezifisch: Sie können nicht testen, ob ein Datensatz bereits persistiert wurde, indem Sie prüfen, ob das Feld Id gesetzt wurde. Man könnte darüber streiten, ob Sie solche Prüfungen überhaupt brauchen.
Fazit
UUIDs sind einfach zu verwenden, aber wäre es nicht schön, wenn sich die JPA-Spezifikation öffnen würde, um UUIDs als Strategie aufzunehmen? Einige JPA-Implementierungen, wie z.B. Hibernate, bieten bereits Unterstützung dafür:
@Id @GeneratedValue(generator="system-uuid") @GenericGenerator(name="system-uuid", Strategie = "uuid")
Eine Liste aller Blogs zu JPA-Implementierungsmustern finden Sie in der Zusammenfassung der JPA-Implementierungsmuster.
Verfasst von
Albert Sikkema
Unsere Ideen
Weitere Blogs
Contact



