Spring-JPA: Update der übergeordneten Entität ausfällt andauern neue untergeordnete Entitäten, interpretieren Sie als Transient statt

Ich bin neu in Spring/JPA/Hibernate, und während es klingt einfach, die Realität einfach noch nicht. Ich könnte etwas Hilfe gebrauchen.

Habe ich eine übergeordnete Entität, die über eine Liste von Kind-Entitäten. Ich werde diese verwenden, um halten Sie die Diskussion einfach:

@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="parent")
    private List<Child> children= new ArrayList<Child>();

    etc...
}

@Entity
public class Child {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private Parent parent;

    etc...
}

@Repository
public interface ParentRepository extends JpaRepository<Parent, Long> {};

Runde 1, ich erstelle ein neues Elternteil und einem neuen Kind, fügen Sie die Kind, um die Eltern-Liste und der Eltern auf das Kind. Wenn ich die Eltern das Kind ebenfalls gespeichert.

@Transactional(propagation=Propagation.REQUIRES_NEW)
void create() {
    Parent parent = new Parent();
    Child  child  = new Child();
    parent.add(child);
    child.setParent(parent);
    parent = repository.save(parent);
}

Nun Runde 2, ich füge ein neues Kind:

@Transactional(propagation=Propagation.REQUIRES_NEW)
void update() {
    Parent parent = repository.findOne(parentID);
    Child newChild = new Child();
    newChild.setParent(parent);
    parent.add(newChild);
    parent = repository.save(parent);
}

Aber dieses mal ist die neue Kind ist nie beibehalten!

Ich habe versucht, die meisten jede Art von CascadeType, @GeneratedValue GenerationType, @Transactional Vermehrung geben...

Tracing dies durch hibernate (schmerzhaft!), hier ist, was ich gefunden habe:

  • Beim speichern das zweite mal, das problem ist mit dem zweiten (neuen) Kindes.
  • Das Problem scheint zu sein, dass, wenn es darum geht, Zeit zu bestehen, den Eltern die Child-Liste
    das neue Kind ist nicht in der EntityManager (noch) und damit als Vorübergehend.
  • Als Ergebnis, es ist tatsächlich überliefert worden sein, die Kette als null, was im folgenden:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is
javax.persistence.RollbackException: Error while committing thetransaction
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
...

Caused by: javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
...

Caused by: org.hibernate.AssertionFailure: collection [null] was not processed by flush()
    at org.hibernate.engine.spi.CollectionEntry.postFlush(CollectionEntry.java:225)
...
  • Es relevant sein könnte, dass in meinem eigentlichen code "Kind" hat auch eine Karte von Kind-Entitäten. Dieser "Wert" ist, was wird weitergegeben als null aufgrund der "Vorübergehende" Zweckentfremdung.
  • Ich habe mit repository.saveAndFlush (), um die Dinge synchron zum Debuggen. Wenn ich nur .save() my @PreUpdate EntityListener heißt aber @PostUpdate Hörer nie.
  • Es scheint, dass es kein problem wäre, wenn das Kind wurden nur beibehalten oder eine Id-zumindest vor dem fortbestehen Eltern. Aber es scheint auch kontraproduktiv, um dies manuell tun. Noch, das ist die einzige alternative die ich mir denken kann.

Vielen Dank für das Lesen. Jede Hilfe wäre sehr geschätzt werden!

  • Leider sehen wir nicht in Ihrer stacktrace, die Sammlung ist null. Könnte es sein, dass die Karte nicht initialiezed in Ihrem Kind? Sie könnten versuchen, weisen Sie eine neue hashmap zu den Feld-Attribut direkt zu testen, ob es behebt den Fehler? Hibernate hat einige Macken mit genullt, Sammlungen. Versuchen Sie, um sicherzustellen, dass die Sammlungen nicht null und wiederholen Sie Ihren test.
  • Danke für Antworten, Martin. Die null ist das Kind, das Kind. In der Objekt-es ist eine Karte, die Objekte, die Sie in es. Allerdings, wenn die Eltern beibehalten wird, Hibernate sieht das Kind, nicht sehen es in der EntityManager, der entscheidet, Sie muss vorübergehend sein und so nur setzt seinen Wert auf null (in einer Identitäts-Karte, nicht auf das original-Objekt). Funktioniert Hibernate haben ein Problem mit den Karten im besonderen?
  • Hibernate habe ein Problem mit Sammlungen wäre zu viel zu sagen. Aber Sammlungen kann schwierig sein zu behandeln. Wir lief in einige Probleme mit orphan removal (=true), wenn wir ersetzt einige Sammlungen komplett. Zum Glück für uns, diese Dinge werden normalerweise beschrieben durch die Menschen und die Dokumentation sehr gut und wir lösen es schnell, sobald Sie wissen, was Sie suchen. Grundsätzlich sollte man nicht erneut initialisieren, Sammlungen, sobald Sie einmal vorhanden, aber mit klarem statt. Deshalb hatte ich diese Idee für dein problem. Das einfachste könnte sein, erstellen Sie einen Testfall mit A, B und C und führen Sie ihn, um Ihr problem.
  • Aye. Nicht sehen, Sie löste es bereits. Also vergiss meinen Kommentar oben über den testcase -:) ist Es wahr, dass Sie keine änderungen machen / Abfragen in eine entitylistener. Ich denke nicht, dass es schlechte Praxis (ak-db-trigger), aber es kann schwierig sein zu Steuern. Hauptproblem ist hier, dass die ActionQueue von Hibernate ist schon gebaut oder wird in der Bauphase.
  • Auf der anderen Seite Envers tut genau dies, aber Sie verwalten die zusätzliche Arbeit, die in so genannten Arbeiter befestigt, um die beforetransaction complete-Ereignis. Anstatt die änderungen direkt Sie einen anderen bauen, der ActionQueue verarbeitet werden. Gebaut haben wir eine E-Mail-system die gleiche Weise wie envers und läuft als erwartet.
  • Ich würde angeschaut Envers eine Weile zurück. Es sah perfekt aus, außer wir haben einige spezielle Bedürfnisse, die gebaut werden müssen sowieso. Trotzdem, es sah schön.

InformationsquelleAutor Didjit | 2013-02-26
Schreibe einen Kommentar