【问题标题】:Remove Order in hibernate在休眠中删除订单
【发布时间】:2023-03-13 06:36:01
【问题描述】:

我有 4 个实体:

Profile与companyContract有关系:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "profile", cascade = { CascadeType.ALL })
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<CompanyContract> companyContracts;

CompanyContract与时间表有关:

@OneToMany(mappedBy = "companyContract", cascade = { CascadeType.ALL },orphanRemoval = true, fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Timesheet> timesheets;

    @ManyToOne
@JoinColumn(name = "IDPROFILE")
private Profile profile;

时间表与发票有关系:

@OneToMany(mappedBy = "timesheet", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Invoice> invoices;

@ManyToOne
@JoinColumn(name = "IDCONTRACT")
private CompanyContract companyContract;

发票:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_TIMESHEET")
private Timesheet timesheet;

所以正如您在此处看到的,我正在使用 org.hibernate.annotations.CascadeType.DELETE_ORPHAN,因此我可以删除父级的子级。

如果我执行这个:

Profile p = companyContract.getProfile();
p.getCompanyContracts().remove(companyContract);
companyContract.setProfile(null);
profileService.update(p);

--->删除顺序应该是:

删除发票 --> 时间表 --> CompanyContract,否?

相反,我收到了这个错误:

org.hibernate.exception.ConstraintViolationException:列“IDCONTRACT”不能为空

我查了一下,这个错误发生在profileService.updateProfile(p);之后

【问题讨论】:

  • 您是否尝试在@JoinColumn 上设置nullable=false,在@ManyToOne 上设置optional=false?这可能会阻止第一次更新为 null,然后再删除
  • 实际上我没有,但你能向我解释一下这些更改将如何阻止你所说的,因为这正是我的问题
  • 您需要@ManyToOne 注释吗?通常不需要明确指定目标实体,因为它通常可以从被引用的对象的类型中推断出来。只是一个想法。
  • 无论如何,是的,您不能只将profile 设置为null
  • @JoinColumn@ManyToOne 的那些属性只是限制了更多的映射,并且可能使 hibernate 在生成 sql 查询时做出正确的决定。

标签: java mysql spring hibernate


【解决方案1】:

问题似乎是包含 Timesheets 的表中的列 IDCONTRACT 具有 NOT NULL 限制。删除它,然后重试。

如果您要自动生成架构,请尝试将 @Basic(optional = true) 添加到 Timesheet.companyContract:

@Basic(optional = true)
@ManyToOne
@JoinColumn(name = "IDCONTRACT")
private CompanyContract companyContract;

【讨论】:

    【解决方案2】:

    这完全正常。我看到所有关联的子实体都已成功删除。

    检查下面的代码。

    使用 orphanRemoval = true 如下所示,而不是弃用的方式 org.hibernate.annotations.CascadeType.DELETE_ORPHAN,您正在使用。

    @OneToMany(mappedBy = "companyContract", cascade = { CascadeType.ALL },orphanRemoval = true, fetch = FetchType.EAGER)
    

    在下面找到代码

    public void check() {
    
        System.out.println("Start check() in DummyDAOImpl");
        Session session = sessionFactory.openSession();
    
        CompanyContract companyContract = session.get(CompanyContract.class, 2);
        Profile p = companyContract.getProfile();
        p.getCompanyContracts().remove(companyContract);
        companyContract.setProfile(null);
        session.update(p);
    
        session.flush();
        session.close();
    
        System.out.println("Executed check() in DummyDAOImpl");
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 2011-02-16
      • 2012-02-07
      • 2010-11-03
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多