【问题标题】:Check for foreign key constraint violation before delete删除前检查外键约束违规
【发布时间】:2019-06-04 18:21:48
【问题描述】:

我正在尝试确定是否可以从存储库中删除对象。换句话说:删除是否会导致 DataIntegrityViolationException。 这是为了在无法删除时隐藏前端的“删除”按钮。

示例: 我有 A 类和 B 类:

@Entity
public class A{
    @Id
    private UUID id;

    @Column
    private String name;

    @ManyToMany
    private Set<B> bs= new HashSet<>();

    //getter, setter, equals,...
}
@Entity
public class B{
    @Id
    private UUID id;

    @Column
    private String name;

    //getter, setter, equals,...
}

现在,如果我想删除任何 A 对象集中的 B 对象,我将得到“DataIntegrityViolationException”。当然,因为对象正在积极用作键。

我想先检查 A,看看是否有任何引用,我可以安全地删除我的 B 实例。但实际上这可能有点棘手,因为不止一个类可以使用 B 类,而其他类将由不熟悉代码的其他人稍后添加。还有这个……

aRepository.findAll(Example.of(new A(null, null, new HashSet<>(Array.asList(b))));

结果只交付了绝对垃圾(>20 多个对象用于 a b 无处使用)。

第二个想法是尝试这样的事情:

    @Transactional //always roll back
    public void inUse(B b) throws TransacationException{
        bRepository.delete(composition);
        throw new TransacationException();
    }

然后像这样检查它:

    public Boolean deleteAble(B b){
        try{
            inUse(b);
        } catch (DataIntegrityViolationException e){
            return false; // constraint violation --> in use!
        } catch (TransacationException e){
            return true;
        }
    }

不幸的是,这些方法似乎都不起作用。 你知道如何解决这个问题吗?

【问题讨论】:

  • 多对多意味着有一个中间表,其中类型 A 的 id 由 B 类型的 id 引用。简单检查此表中是否存在 id 将确定数据有引用,因此不能被删除。
  • 这个表当然存在,但完全由 Spring Data 管理,我真的不知道无需手动实现即可访问此表的好方法。这也不包括我不知道的实体可能引用我的情况。
  • 这可能也有帮助 - stackoverflow.com/questions/2109476/…

标签: java spring spring-data-jpa


【解决方案1】:

也许你可以让你的 @ManyToMany 关联是双向的,比如将它添加到你的班级 B

@ManyToMany(mappedBy = "bs")
private Set<A> as = new HashSet<>();

那么它只会像:

someB.getAs().isEmpty()

【讨论】:

  • 我同意,这会避免很多麻烦,但不幸的是,这似乎不适用于这种特殊情况:(
  • @floo 是您无法更改 B 还是出现错误?如果只是不工作,您可以尝试显式声明 many2many 映射表,而不是让 JPA 从默认值创建它。如果您在之前的尝试中已经存在之前的映射表,它可能无法正常工作。
猜你喜欢
  • 2021-05-09
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 2020-08-10
相关资源
最近更新 更多