Java JPA&x2B@OneToMany+;删除:如果我以后访问父项,则不会删除该项
我得到了一个Java JPA&x2B@OneToMany+;删除:如果我以后访问父项,则不会删除该项,java,postgresql,hibernate,jpa,cascade,Java,Postgresql,Hibernate,Jpa,Cascade,我得到了一个交易,它可以有多个交易项目 DealItems在Deal中通过以下JPA注释链接: public class DealEntity extends BasicEntity { @OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<DealItemEntity> items; ... 当我删除DealItem时,它会被
交易
,它可以有多个交易项目
DealItems
在Deal
中通过以下JPA注释链接:
public class DealEntity extends BasicEntity {
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
...
当我删除DealItem
时,它会被删除并再次分发,当我在删除后访问Deal
时,请参见此处:
public FullDealResponse deleteDealItem(final String dealCode, final long dealItemId) {
DealEntity dealEntity = dealControl.findDealByDealCode(dealCode);
if (dealEntity == null) {
throw new WorkbenchGenericErrorException("Deal not found");
}
DealItemEntity dealItemEntity = dealItemControl.findDealItemByIdAndDealId(dealItemId, dealEntity.getId());
if (dealItemEntity == null) {
throw new WorkbenchGenericErrorException("Deal item not found");
}
// this makes a database DELETE call that is executed after the session is done
dealItemControl.deleteDealItem(dealItemEntity);
// When I remove this and I do not return anything, the deletion works
return this.getFullDealResponse(dealEntity);
}
编辑:
这是getFullDealResponse()
和getFullDealItemResponse()
:
当我切换级联类型时可以解决这个问题吗?如果可以,哪种类型是正确的?或者我必须迭代Deal.getItems()
,删除不需要的项目,使用Deal.setItems()
设置新列表,并仅更新Deal
,以便它传播删除
这样做的首选方式是什么
我已经在本地复制了这段代码并验证了我的解释
摘要:
级联没有影响。即使删除级联操作,也要单独保存每个项,然后使用此方法时,它也不会删除您的项
要在不考虑deal.getItems
初始化的情况下具有相同的行为,除了直接删除dealItem之外,还必须通过从deal.getItems
中删除dealItem
在双向关系中,您必须明确管理双方。与此完全相同,您可以在保存之前将dealItem添加到dealItem,并设置dealItem的deal字段
总体解释
- JPA只能有一个与会话关联的特定项的表示
>P>是提供<强>重复读取、脏检查< /强>等的基础。
- JPA还跟踪与其会话关联的每个对象,如果任何被跟踪的对象有更改,则在提交事务时将刷新这些对象
- 当只有
deal
对象(带有惰性deaItems
集合)和直接获取的dealItem
是与会话相关联的仅有两个实体时,那么JPA在会话中每个都有一个表示,因为删除它时没有冲突,它通过dealItemControl将其删除。deleteDealItem
dealItem已删除
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
- 但是,一旦调用
deal.getItems
,JPA不仅管理deal,而且还管理与deal
对象关联的每个dealItem。因此,当您删除dealItemControl.deleteDealItem
时,JPA有一个问题,因为deal.getItems告诉它未标记为删除。因此,删除未发布
参考:生成的JPA QL也证实了我的解释
1。使用deal.getItems
和生成的查询
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
2。没有deal.getItems
和生成的查询
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
@KavithakaranKanapathippillai I添加了2个响应functions@KavithakaranKanapathippillai谢谢,我添加了delete函数为什么要用那些包装器方法和实体引用使删除复杂化?为什么不在需要的地方使用em.remove(dealItemEntity)
呢?@pirho这是一个巨大的项目,我没有做基础设置,改变它意味着大量重构(项目中使用ECB模式)。此外,我不认为移除包装会解决问题,因为问题在于KavithakaranKanapathippillai提到的双向关联。非常感谢您的时间和详细回答!
@OneToMany(mappedBy = "deal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DealItemEntity> items;
DealEntity dealEntity = dealControl.findDealByDealCode(dealCode);
....
dealItemControl.deleteDealItem(dealItemEntity);
select deal0_.* from deal deal0_ where deal0_.id=?
select dealitem0_.*
deal1_.*
from
deal_item dealitem0_ inner join deal deal1_ on dealitem0_.deal_id=deal1_.id
where
dealitem0_.id=?
delete from deal_item where id=?