首页 > 解决方案 > 使用 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,但对于一个策略的所有版本,保险 ID 保持相同。

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

我想过以下几种方法,但我对其中任何一种都不满意:

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

任何帮助将不胜感激。我使用 EclipseLink。

标签: jpaeclipselink

解决方案


我尝试向数据库添加约束,但 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;
}

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


推荐阅读