Каскад - JPA & Hibernate аннотация распространенная ошибка
Часто разработчики смешивают использование аннотаций JPA и Hibernate вместе, это может привести к очень распространенной ошибке - аннотации каскадного типа JPA не работают в Hibernate?
В разделе обзора кода я обнаружил, что многие Java-разработчики не знают об этой ошибке и из-за того, что программе не удалось выполнить каскадную операцию для связанных объектов. Я возьму этотone-to-many hibernate example для демонстрации.
ошибка
В примере «один ко многим» многие разработчики объявили следующие параметры каскада JPA:
... @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; } ...
Сохраните его с помощью Hibernate.
stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.getTransaction().commit();
Код, который пытается сделать, это когда вы сохраняете «сток», он также сохраняет и связанный с ним stockDailyRecords. Все выглядит нормально, ноTHIS IS NOT WORKING, параметры каскада не будут выполняться и сохранять stockDailyRecords. Вы можете заметить ошибку?
объяснение
Посмотрите код,@OneToMany из JPA, он ожидал каскад JPA -javax.persistence.CascadeType. Однако, когда вы сохраните его в сеансе Hibernate,org.hibernate.engine.Cascade выполнит следующую проверку ...
if ( style.doCascade( action ) ) { cascadeProperty( persister.getPropertyValue( parent, i, entityMode ), types[i], style, anything, false ); }
Процесс сохранения гибернации вызовет действиеACTION_SAVE_UPDATE, но JPA передастACTION_PERSIST иACTION_MERGE, это не будет соответствовать и приведет к сбою выполнения каскада.
@ смотри исходный код
-
org.hibernate.engine.Cascade
-
org.hibernate.engine.CascadeStyle
-
org.hibernate.engine.CascadingAction
Решение
Удалите каскад JPA -javax.persistence.CascadeType, замените его каскадом Hibernate -org.hibernate.annotations.Cascade, наCascadeType.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; } ...
Теперь это работает так, как вы ожидали.
Заключение
Это похоже на несовместимую проблему между JPA и каскадной аннотацией Hibernate, если Hibernate является реализацией JPA, что может вызвать неправильное понимание между ними?