Cascade - JPA & Hibernate Annotation häufiger Fehler
Häufig werden Entwickler die JPA- und Hibernate-Annotation gemischt verwenden. Dies führt zu einem sehr häufigen Fehler. Funktioniert die JPA-Kaskaden-Annotation im Hibernate-Modus nicht?
Während der Codeüberprüfung stelle ich fest, dass viele Java-Entwickler diesen Fehler nicht kennen und das Programm die Kaskadenoperation für die zugehörigen Entitäten nicht ausführen konnte. Ich werde dieseone-to-many hibernate example für die Demonstration nehmen.
Fehler
Im Eins-zu-Viele-Beispiel haben viele Entwickler die JPA-Kaskadenoptionen wie folgt deklariert:
... @Entity @Table(name = "stock", catalog = "example", uniqueConstraints = { @UniqueConstraint(columnNames = "STOCK_NAME"), @UniqueConstraint(columnNames = "STOCK_CODE") }) public class Stock implements java.io.Serializable { ... private SetstockDailyRecords = new HashSet (0); @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,CascadeType.MERGE }, mappedBy = "stock") public Set getStockDailyRecords() { return this.stockDailyRecords; } public void setStockDailyRecords(Set stockDailyRecords) { this.stockDailyRecords = stockDailyRecords; } ...
Speichern Sie es mit Ruhezustand.
stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.getTransaction().commit();
Der Code, der versucht zu tun, ist, wenn Sie eine "Aktie" speichern, speichert er auch die zugehörigen stockDailyRecords. Alles sieht gut aus, aberTHIS IS NOT WORKING, die Kaskadenoptionen werden nicht ausgeführt und speichern die stockDailyRecords. Kannst du den Fehler erkennen?
Erläuterung
Schauen Sie in den Code,@OneToMany ist von JPA, es wurde eine JPA-Kaskade erwartet -javax.persistence.CascadeType. Wenn Sie es jedoch mit einer Sitzung im Ruhezustand speichern, führtorg.hibernate.engine.Cascade die folgenden Überprüfungen durch:
if ( style.doCascade( action ) ) { cascadeProperty( persister.getPropertyValue( parent, i, entityMode ), types[i], style, anything, false ); }
Der Speichervorgang im Ruhezustand führt zu einer Aktion vonACTION_SAVE_UPDATE, aber der JPA übergibtACTION_PERSIST undACTION_MERGE. Er stimmt nicht überein und führt dazu, dass die Kaskade nicht ausgeführt werden kann.
@Siehe Quellcode
-
org.hibernate.engine.Cascade
-
org.hibernate.engine.CascadeStyle
-
org.hibernate.engine.CascadingAction
Lösung
Löschen Sie die JPA-Kaskade -javax.persistence.CascadeType und ersetzen Sie sie durch die Hibernate-Kaskade -org.hibernate.annotations.Cascade durchCascadeType.SAVE_UPDATE.
... @Entity @Table(name = "stock", catalog = "example", uniqueConstraints = { @UniqueConstraint(columnNames = "STOCK_NAME"), @UniqueConstraint(columnNames = "STOCK_CODE") }) public class Stock implements java.io.Serializable { ... private SetstockDailyRecords = new HashSet (0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock") @Cascade({CascadeType.SAVE_UPDATE}) public Set getStockDailyRecords() { return this.stockDailyRecords; } public void setStockDailyRecords(Set stockDailyRecords) { this.stockDailyRecords = stockDailyRecords; } ...
Jetzt funktioniert es so, wie Sie es erwartet haben.
Fazit
Es sieht aus wie ein inkompatibles Problem zwischen JPA- und Hibernate-Kaskadenanmerkung. Wenn Hibernate eine JPA-Implementierung ist, was kann das Missverständnis dazwischen verursachen?