【发布时间】:2017-02-11 22:44:45
【问题描述】:
我最近发现了用于审计的 envers,并且能够成功地使用它来跟踪修订并使用 @Audited 注释和 AuditReader 获取它们。现在,我想要实现的是将映射保留到被审计实体的修订版而不是最新修订版。
快速示例:
假设我有一个饼干配方,我用它来制作一批饼干(下面的类的伪类)。每个配方都有一个要遵循的说明列表,这样做会创建一个批次:
@Audited
@Table(name="recipes")
class CookieRecipe {
@OneToMany(mappedBy="recipe")
private List<RecipeStep> steps;
private void addStep(String instruction) {
steps.add(new RecipeStep(instruction));
}
}
@Table(name="batches")
class CookieBatch {
@ManyToOne
@JoinColumn(...)
private CookieRecipe recipe;
}
@Audited
@Table(name="recipe_step")
class RecipeStep {
@Column
private String instruction;
@ManyToOne
@JoinColumn(...)
private CookieRecipe recipe;
private RecipeStep(String instruction) {
this.instruction = instruction;
}
}
现在,假设我有这个饼干食谱:
CookieRecipe recipe = new CookieRecipe();
recipe.addStep("Make the dough");
recipe.addStep("Place on pan");
recipe.addStep("Bake at 400F for 20 minutes");
entityManager.persist(recipe);
我将使用这个食谱来制作我的第一批饼干:
CookieBatch batch = new CookieBatch(recipe);
entityManager.persist(batch);
如果我想将配方更改为例如 375F 而不是 400F,这将创建 CookieRecipe 的修订版 2,这是我所期望和想要的。但是,我希望我已经创建的批处理指向 CookieRecipe 的修订版 1。目前,如果我使用它的 ID 获取我已经创建的CookieBatch,那么对CookieRecipe 的引用最终会成为最新版本(具有 375F 的版本)。
这是我可以使用 envers 完成的事情吗?
【问题讨论】:
-
CookieBatch不是@Audited是故意的吗?如果是这样,我不相信有一种优雅的方式来做你想做的事情。 -
@SergeiBednar 是的,唯一的原因是一旦
CookieBatch完成,它就不会改变。所以我认为这是不必要的,因为它只会创建一个永远不会真正使用的审计表......除非我误解了这种行为。如果它导致解决方案,我不反对添加@Audited。 -
我认为您唯一的其他解决方案是保留
recipeId和recipeRevisionNumber值,将CookieBatch中的recipe实体更改为@Transient,并处理查询在加载CookieBatch实体后,通过 enversAuditCriteria自己制作配方。 -
@SergeiBednar 我认为这将是适合我的解决方案,介意将其作为解决方案发布吗?此外,您是否了解在持久化
CookieBatch时如何获取recipeRevisionNumber? -
此时
CookieRecipe应该保持不变,您可以通过审核标准获得最新版本。查看此文档,它非常可靠:docs.jboss.org/envers/docs
标签: hibernate jpa hibernate-envers