[JAVA] Das süchtig machende Memo von SpringBoot-JPA-Hibernate

Über diesen Artikel

Dieser Artikel fasst zusammen, wovon ich bei der Entwicklung der Anwendung abhängig war, und, falls gefunden, Ursache und Lösung. Es kann Fälle geben, in denen das Problem in diesem Artikel auftritt, die Verwendung jedoch in erster Linie falsch ist oder es eine bessere Lösung gibt.

Umgebung

Probleme aufgetreten

Ich erhalte eine Fehlermeldung, wenn ich eine Zuordnung zu einem anderen Schlüssel als PK herstelle

Wie bei Datenbanken üblich, kann es bei der Implementierung von Hibernate zu Problemen kommen.

Anwendungsfall

@Entity
class Parent {
    @Id
    Long id;
    @NatulalId
    Integer key;
    String firstName;
    String lastName;
}

@Entity
class Child {
   @Id
   Long id;
   @ManyToOne
   @JoinColumn(name = "parent_key",referencedColumnName = "key")
   Parent parent;
}

In der obigen Verwendung, in der die von Hibernate selbst empfohlene PK der Ersatzschlüssel ist und der natürliche Schlüssel durch "@ NaturalId" angegeben wird, wird der Schlüssel innerhalb des Bereichs der JPA-Spezifikationen als eindeutig und anstelle der ID angegeben. Wenn Sie als externer Schlüssel fungieren möchten. Wenn Sie einem natürlichen Schlüssel zuordnen, tritt ein Fehler aufgrund der Cast-Beteiligung bei der Ausführung von child.getParent () usw. auf. [^ 1] [^ 1]: Es scheint nicht immer zu passieren, und es scheint, dass häufig Fragen dazu gestellt werden.

Ursache

Offizieller Issue Tracker HHH-7668

Lösung

Machen Sie die referenzierte Entität (Eltern oben) sirialisierbar. In diesem Sinne ist es möglicherweise sicherer, dass alle im Ruhezustand verwendeten Entitäten sirialisierbar sind.

Ein kurzer Blick auf den Issue-Tracker zeigt, dass andere Probleme auftreten können, wenn Sie ihn einer eindeutigen Spalte zuordnen, die keine PK ist.

Nachtrag 2020/05/28 Über Sirializable of entity

Aufgrund der JPA-Spezifikationen ist Sirializable nicht erforderlich, wenn eine Entität nur mit DB ausgetauscht wird. Sirializable einer Entität ist jedoch erforderlich, wenn sie im Rahmen von JavaEE verwendet wird, z. B. zum Speichern als Objekt in einer HTTP-Sitzung. Wie es scheint. In Anbetracht der Tatsache, dass ein Fehler an einem unerwarteten Ort auftritt, scheint es wünschenswert zu sein, sirialisierbar zu sein.

Die Entität FetchType.Lazy löst beim Serialisieren durch Jackson einen Fehler aus

Ursache

Weil die Substanz der von Lazy angegebenen Eigenschaft, auf die Jackson beim Serialisieren zugreift, ein Hibernate-Proxy ist

Lösung

Fügen Sie das Jackson-Plug-In für die Hibernate-Version hinzu. Spring Boot hängt standardmäßig von Hibernate und Jackson ab. Warum ist dies nicht enthalten? [^ 2] [^ 2]: Ich habe beim Schreiben des Artikels bemerkt, dass er in Spring Data REST Web MVC enthalten ist ... Warum? Stapelüberlauf: Kein Serializer für ... gefunden? Stack OverFlow: Einstellung zum Unterdrücken des Lazy-Attributs in Jackson of Spring Jeder hat es schwer.

Lösen des Problems, dass die Jackson-Serialisierung der Spring JPA-Entität auch Lazy auslöst Das Obige ist eine sehr einfache Erklärung und Lösung.

Nur für den Fall, es ist Plug-in GitHub. Der Inhalt ist nicht sehr nett. Übrigens wurde Erklärung der Ausgabesteuerung durch Jacksons Annotation (Endlosschleifen-Workaround) im obigen GitHub eingeführt.

Ein Fehler in Bezug auf den Spalten- oder Tabellennamen wird angezeigt (Hinzufügung / Korrektur 2020-02-21).

Dies ist eine Spezifikationsgeschichte. Es ist kein Fehler.

Ursache

~~ Die Standardbenennungsstrategie wird nach der JPA-Annotation ~~ verarbeitet

~~ Wenn eine Anmerkung, die einen JPA-Tabellennamen (or Ruhezustand) oder einen Spaltennamen angibt, nur aufgrund des Prioritätsproblems verwendet wird, tritt ein Fehler auf, da die Konvertierung des Spaltennamens aus dem Feldnamen nicht verarbeitet wurde. ~~

Ich habe die Spezifikationen nicht verstanden. Im Ruhezustand wird der DB-Spaltenname durch eine zweistufige Konvertierung generiert.

  1. Generieren Sie einen logischen Namen aus dem Entitätsnamen und dem Feldnamen
  2. Konvertieren Sie logische Namen in physische Namen

Die aktuelle Spring-Standardeinstellung ist

  1. Generierung eines logischen Namens
  1. Generierung eines physischen Namens

Es ist eingestellt als.

Da die durch @ Column oder @ Table angegebene Zeichenfolge in ** logischer Name ** geändert wird, sollte der in der Anmerkung angegebene Name nicht in den Kamelfall geändert werden, wenn der Feld- oder Klassenname im Kamelfall angegeben wird. Darf nicht sein. Wenn hier ein physischer Name (dh ein Schlangenfall) angegeben ist, enthält "Tabelle [Tabellenname] den physischen Spaltennamen [Spaltenname], auf den sich mehrere logische Spaltennamen beziehen:" (logisch entsprechend dem physischen Spaltennamen der Tabelle) Ich habe zwei Namen) und ich bekomme eine Fehlermeldung.

Lösung

Wenn der Spaltenname usw. in der ~~ JPA-Annotation angegeben ist, muss der Name im Feld mit "@ Column" angegeben werden. Ich kann nicht mehr als erwartet abschneiden. ~~ [^ 3] [^ 3]: ~~ Ich denke, es kann durch Anpassen der Hibernate-Seite gelöst werden. ~~ Lesen Sie die technischen Daten und Fehlermeldungen richtig durch. Da alle physischen Namen niedriger sind, ist es besser, obere Spaltennamen und Tabellennamen zu verwenden.

apprication.yaml



spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

(Der logische Name wird als physischer Name verwendet). Spring ImplicitNamingStrategy, das Spring standardmäßig verwendet, verwendet jedoch standardmäßig Hicitnates Standard ImplicitNamingStrategyJpaCompliantImpl. Wenn Sie also den Eigenschaftsnamen des Kamelfalls verwenden, ist dies der Spaltenname des Kamelfalls. Lesen Sie stackoverfrow: Beispiel für eine Hibernate-Namensstrategie und wählen Sie die nächstgelegene aus und passen Sie sie mit Anmerkungen an. Überlegen. Wenn es nicht ausreicht, die Strategie von Hibernate abzulenken, müssen Sie sie selbst implementieren. Referenz: Angepasst durch die Strategie der physischen Benennung Angepasst mit ImplicitNamingStrategyJpaCompliantImpl

Ich möchte die zugehörige Entität und den tatsächlichen Wert des Schlüssels in verschiedenen Eigenschaften haben

Dies ist kein Problem, es ist ein Tipp. Dies ist eine bequeme Möglichkeit, eine Entität zu erstellen, die den tatsächlichen Wert des Schlüssels in einer Eigenschaft beibehalten und der Zuordnung nur bei Bedarf folgen möchte.

Lösung

Deaktivieren Sie das Aktualisieren und Einfügen verwandter Entitäten mit "@ JoinColumn"

@Entity
class Parent {
    @Id
    Long id;
    @NatulalId
    Integer key;
    String firstName;
    String lastName;
}

@Entity
class Child {
   @Id
   Long id;
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "parent_key",referencedColumnName = "key",
        insertable = false, updatable = false)
   Parent parent;
   @Column(name="parent_key")
   Integer parentKey;
}

Wenn Sie eine Klasse wie die oben beschriebene verwenden, können Sie auf den Elternteil verweisen, während Sie den Schlüssel direkt gedrückt halten, und verhindern, dass das Kind den Elternteil aktualisiert. Ändern Sie beim Aktualisieren der Referenz direkt den Wert des Schlüsselfelds (in diesem Beispiel parentKey). Diese Form eignet sich sehr gut für Objekte, die auf Stammdaten verweisen.

Recommended Posts

Das süchtig machende Memo von SpringBoot-JPA-Hibernate
Ganzzahliges Memo
Docker-Memo
Lombok Memo
Dockerfile-Memo
Java-Memo
AWS-Memo
Dcokerfile Memo
Memo Stream