JPA 不可修改的数据库行

JPA unmodifiable database row

问题

我目前正在研究 Spring-应用程序作为大学项目的一部分,我们 运行 遇到以下问题:

我有一个 JPA 实体,它对 State 的 table 进行建模,我想要一个硬编码的 End-State,它始终存在于数据库中并且不能被删除或修改。在最好的情况下,它应该有一个特殊的 id(例如 0),因此可以很容易地从应用程序中引用它。

我也无法将 State 建模为枚举,因为它们必须在 运行 时可配置。

代码

实体看起来像这样(缩写):

@Entity
public class BillingItemState {

    @Autowired
    private BillingItemStateRepository billingItemStateRepository;

    @Id
    private String id;

    @NotEmpty
    private String name;

    @ManyToMany
    private List<BillingItemState> parentStates = new ArrayList<>();

    @ManyToMany(mappedBy = "parentStates", cascade = CascadeType.PERSIST)
    private List<BillingItemState> nextStates;
}

到目前为止我尝试了什么

我试图通过使用 @PrePersist@PreUpdate@PreDelete 来强制执行该规则,但这似乎不是一个很好的解决方案,因为我没有办法在创建数据库时插入结束状态。我也想到了相当不优雅的解决方案,比如为不可修改的 Final-State 拥有自己的 Table,但这也会引发一些问题。

有没有更合适table的模式来完成这个任务?我觉得我走错了路。

(另外,这是我的第一个问题。如果您对我的问题有任何改进,请评论它们:)

我想你需要的是@Immutable

此注释允许您使行不可变(您将无法进行任何更新)。

但是插入动作仍然可以像删除一样。

要摆脱删除的可能性,您可以尝试 @PreRemove 抛出一些异常或任何不同的逻辑。

initialise database statedata.sql文件应该不错

你也可以考虑Flyway or Liquibase.

其他资源

  1. 关于 @Immutable
  2. 的文章
  3. Immutable user guide
  4. @PreRemove
  5. Spring docs about data.sql and database initialisation

我会说,如果可以的话,请尝试将 Final 状态建模为某种属性,即 boolean isEnd。这样你删除或设置静态数据就没有问题了。