【问题标题】:How to Enforce Foreign Key Constraint on Delete with JPA and H2 Database如何使用 JPA 和 H2 数据库在删除时强制执行外键约束
【发布时间】:2021-07-19 19:28:10
【问题描述】:

我有一个 Spring Boot 应用程序,它在 h2 数据库中有 2 个表:Computer 和一个Processor。

计算机和处理器之间存在单向、多对一关系,因此许多计算机可以拥有一个处理器。

@Entity
@Table(name = "Computer", schema = "CS")
public class Computer extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "computer_id")
    @Getter
    @Setter
    private long id;
    ...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "processor_id")
    @OnDelete(action= OnDeleteAction.NO_ACTION)
    @Getter
    @Setter
    private Processor processor;
    ...
}

@Entity
@Table(name = "Processor", schema = "CS")
public class Processor extends BaseEntity {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "processor_id")
     @Getter@Setter
     private long id;
    ...
}

我想在数据库级别强制执行,当我尝试删除至少被一台计算机引用的处理器时,由于外键约束,JPA 不允许完成删除。

我了解此功能可以通过编程方式完成,例如查找与某个处理器相关联的所有计算机,但这似乎是一种代码异味,最好让 JPA 注释为我处理这个问题,如果这是可能的。

谢谢!

【问题讨论】:

  • 您可以添加一个名为“isDeleted”布尔值的额外列,并在删除时将其设置为 true - 快速修复。
  • 谢谢,但是这个要求将在我的应用程序的许多表中,我不想不必要地使数据库复杂化。
  • JPA 是否定义了您的 DDL?如果是这样,它应该自动将 processor_id 连接列定义为具有约束的外键,防止您让该列引用有效处理器行以外的内容。

标签: database spring-boot jpa foreign-keys constraints


【解决方案1】:

尝试使用 @ForeignKey 注释,我以前没有使用过它,但从文档中它应该可以满足您的需求: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/ForeignKey.html

另一种方法是使用实​​体生命周期回调(请参阅https://www.baeldung.com/jpa-entity-lifecycle-events)。 @PreRemove 方法,您可以在其中检查是否有任何实体依赖于您要删除的实体并抛出自定义运行时异常......但第一种方法应该足够了

【讨论】:

    【解决方案2】:

    感谢您的帮助;我已经解决了这个问题。 我的数据库架构中的外键约束存在错误。注释工作正常,不需要@OnDelete(action= OnDeleteAction.NO_ACTION) 注释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 2017-05-21
      • 2022-01-08
      • 2021-05-09
      • 2019-06-12
      • 1970-01-01
      • 2012-04-04
      相关资源
      最近更新 更多