我们有一个抽象的基本实体类,它定义了在我们所有实体中找到的列(例如,创建和修改时间戳和相关的用户ID)。对于我们的大多数实体,有两个相关的数据库表:一个保存“实时”数据,即实体的当前状态;并且将审计跟踪(即实体的所有历史版本)保存为快照。
所有实体共享的列之一(并在基本实体类中定义)是版本号列,它是一个简单的运行序列,用于说明对该特定实体进行了多少次编辑。版本列存在于审计表和“常规”表中,但在审计表中,版本列也是复合主键的一部分,复合主键是通过组合“常规”实体的主键和版本号。简化示例(为简洁起见省略了一些实体级注释):
@MappedSuperclass
public abstract class BaseEntity {
@Column(name = "version")
private Long version;
// Timestamps, user IDs etc.
}
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class PersonBase extends BaseEntity {
// All basic columns of a person defined here
}
public class Person extends PersonBase {
@Id
@Column(name = "id")
private long id;
// All references to other entities defined here
}
public class PersonAudit extends PersonBase {
@Id
@Column(name = "id")
private long id;
// FIXME: Version column should be part of composite primary key
// All foreign key columns defined here (can't have
// a direct FK relationship in an audit table, as you
// don't know which version to link to)
}
是否可以使继承的版本列成为审计实体中复合主键的一部分?我尝试在PersonAudit
表中声明版本列并添加{ {1}}注释,但之后@Id
中的版本字段不再填充。在BaseEntity
中使用JPA静态元模型在一些通用条件查询中使用该字段时非常方便,如果我们将字段声明移动到各个审计实体,我们就无法引用这些查询中的列。
P.S。我们正在使用Hibernate,因此如果JPA没有启用Hibernate,那么特定于Hibernate的解决方案也是可以接受的。