Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA&x2B@OneToMany+;删除:如果我以后访问父项,则不会删除该项_Java_Postgresql_Hibernate_Jpa_Cascade - Fatal编程技术网

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=?