级联– JPA和Hibernate注释常见错误

通常,开发人员将JPA和Hibernate批注混用在一起,会引起一个非常普遍的错误-JPA级联类型批注在Hibernate中不起作用?

在代码审查部分中,我发现许多Java开发人员都不知道此错误,并导致程序无法对相关实体执行级联操作。 我将以这个一对多的休眠示例进行演示。

错误

在一对多示例中,许多开发人员声明了JPA级联选项,如下所示:

...
@Entity
@Table(name = "stock", catalog = "mkyong", uniqueConstraints = {
		@UniqueConstraint(columnNames = "STOCK_NAME"),
		@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
    ...
    private Set<StockDailyRecord> stockDailyRecords = 
                                              new HashSet<StockDailyRecord>(0);
 
    @OneToMany(fetch = FetchType.LAZY, 
       cascade = {CascadeType.PERSIST,CascadeType.MERGE }, 
       mappedBy = "stock")
    public Set<StockDailyRecord> getStockDailyRecords() {
	return this.stockDailyRecords;
    }
 
    public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) {
	this.stockDailyRecords = stockDailyRecords;
    }
    ...

使用Hibernate会话保存它。

stockDailyRecords.setStock(stock);        
        stock.getStockDailyRecords().add(stockDailyRecords);
 
        session.save(stock);
        session.getTransaction().commit();

该代码尝试执行的操作是在保存“库存”时,还将保存关联的stockDailyRecords。 一切看起来都很好,但是不起作用,级联选项将不会执行并保存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
		);
	}

Hibernate保存过程将导致ACTION_SAVE_UPDATE动作,但是JPA将传递ACTION_PERSISTACTION_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 = "mkyong", uniqueConstraints = {
		@UniqueConstraint(columnNames = "STOCK_NAME"),
		@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
    ...
    private Set<StockDailyRecord> stockDailyRecords = 
                                              new HashSet<StockDailyRecord>(0);
 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
    @Cascade({CascadeType.SAVE_UPDATE})
    public Set<StockDailyRecord> getStockDailyRecords() {
	return this.stockDailyRecords;
    }
 
    public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) {
	this.stockDailyRecords = stockDailyRecords;
    }
    ...

现在,它可以按预期工作。

结论

看起来JPA和Hibernate级联批注之间存在不兼容的问题,如果Hibernate是JPA实现,则可能是什么原因导致两者之间的误解?

翻译自: https://mkyong.com/hibernate/cascade-jpa-hibernate-annotation-common-mistake/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值