使用 JPA 加载实体的最新版本

Load newest version of an entity with JPA

我有以下实体:

@Entity
public class Policy {
  @ID
  private String uuid;

  private String policyId;

  private Long version;

  private Long auditVersion;
}

@Entity
public class PolicySearch {
  @ID
  private String uuid;

  @ManyToOne(optional = false)
  @JoinColumn(name = "policy_id", referencedColumnName = "policy_id")
  private Policy policy;
}

基本上,我有一份保险单,其中所有更改都在数据库 (auditVersion) 中进行跟踪。在一些较小的更改之后可以发布一个版本,这就是版本递增并且 auditVersion 再次从 0 开始的时候。每个数据库条目都有不同的 UUID,但 insuranceId 对于一个保单的所有版本都保持不变。

问题:我有一个搜索实体,搜索总是搜索策略的所有版本——这就是为什么我引用 policyId 而不是 uuid。当 JPA 加载实体时,我最终得到了任何策略。我想要一种方法,在给定引用的 policyId(以及该版本的最高 auditVersion)的情况下始终获得最高版本的策略。

我考虑过以下方法,但我对其中任何一个都不满意:

  1. 将引用的 Policy 的类型从 Policy 更改为 String 并仅保存 policyId,这会起作用,但我仍然想要外键约束,但我似乎找不到用 JPA 创建它的方法注释(JPA 创建我的数据库模式)。
  2. 保持实体不变,但在加载 PolicySearch 后放弃加载的策略以支持最新的策略。这可以在 DAO 中完成,但如果将来有任何实体将 PolicySearch 作为成员,这似乎是一个非常糟糕的主意。

如有任何帮助,我们将不胜感激。我使用 EclipseLink。

我试图向数据库添加约束,但 Postgres 不允许您为不唯一的列添加外键约束。我们的解决方案(我的一位同事提出的)是更改数据库设计并创建一个包含 PolicyId 的新实体。所以我们的实体现在看起来像这样:

@Entity
public class Policy {
  @ID
  private String policyId;
}

@Entity
public class PolicyVersion {
  @ID
  private String uuid;

  private Policy policy;

  private Long version;

  private Long auditVersion;
}

@Entity
public class PolicySearch {
  @ID
  private String uuid;

  @ManyToOne(optional = false)
  @JoinColumn(name = "policy_id", referencedColumnName = "policy_id")
  private Policy policy;
}

这基本上解决了所有的问题,还有一些其他的好处(比如简单的查询)。