Verwenden Sie immer primitive Objekt-Wrapper für JPA @Id anstelle von primitiven Typen?

Ich habe das Problem mit der Verwendung des primitiven Typs als Objekt @Id für JPA in Verbindung mit Spring Data JPA gefunden. Ich habe Eltern / Kind-Beziehung zu Cascade.ALL auf der Elternseite, und Kind hat PK, die gleichzeitig auch die FK der Eltern ist.

class Parent {
    @Id
    private long id;

    @OneToOne(mappedBy = "parent", cascade = ALL)
    private Child child;
}

class Child {
    @Id
    @OneToOne
    private Parent parent;
}

Also, wenn ich renne:

...
Parent parent = new Parent();
Child child  = new Child(parent);
parent.setChild(child);  
em.persist(parent)
...

alles funktioniert gut Aber ich habe Spring Data JPA verwendet, um die Entität beizubehalten, also führe ich stattdessen Folgendes aus:

parentRepository.save(parent); // instead of em.persist(parent);

und dieser war mit der folgenden Ausnahme fehlgeschlagen:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent

Das Problem war, dass Spring Data JPAsparen() Die Methode prüft, ob die Entität neu ist und ob sie dann neu istem.persist () wird anderweitig verwendetem.merge () wird eingesetzt.

Der interessante Teil hier, wie Spring prüft, ob die Entität neu ist oder nicht:

getId(entity) == null;

Und das war natürlich falsch, da ich long als Typ für @Id verwendet habe und der Standardwert für long 0 ist. Wenn ich long zu Long geändert habe, funktioniert alles auch mit Spring Data JPA.

Es wird daher empfohlen, immer Objekt-Wrapper für die primitiven Typen (wie Long statt long) anstelle von primitiven Typen zu verwenden. Alle Ressourcen von Drittanbietern, die dies als empfohlene Vorgehensweise bezeichnen, wären sehr nett.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage