Каскад - 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 Set stockDailyRecords =
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 Set stockDailyRecords =
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, что может вызвать неправильное понимание между ними?