我最近发现了用于审计的envers,并且能够成功地使用它来跟踪修订,并使用@Auded
注释和AuditReader
获取它们。现在,我试图实现的是在修订时保留到审核实体的映射,而不是最新的修订。
快速示例:
假设我有一个cookie配方,我用它来制作一批cookie(下面类的伪类)。每个配方都有一个要遵循的说明列表,这样做会创建一个批次:
@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);
我将使用这个食谱来制作我的第一批cookie:
CookieBatch batch = new CookieBatch(recipe);
entityManager.persist(batch);
例如,如果我想将配方更改为375F而不是400F,这将创建CookieRecipe
的修订版2,这是我所期望和想要的。但是,我希望我已经创建的批次指向CookieRecipe
的修订版1。目前,如果我获取我已经使用其ID创建的CookieBatch
,对CookieRecipe
的引用最终会成为最新的修订版(具有375F的版本)。
这是我可以用envers完成的事情吗?
我相信您做到这一点的唯一方法是在您的CookieBatch
中保留RececpeId
、RececpeRevsionNumber
字段,并自己加载CookieRecipe
对象。
@Table(name="batches")
class CookieBatch {
@Column(...)
Long recipeId;
@Column(...)
Long recipeRevisionNumber;
@Transient
private CookieRecipe recipe;
@PostLoad
public void loadRecipe()
{
// Load a cookie recipe via audit criteria
}
}
审核标准是不言而喻的,看看这个例子:
Hibernate Envers获得标准的修订
和所有事物的留档:
http://docs.jboss.org/envers/docs/
我建议对CookieBatch
进行审计,并在CookieBatch
和CookieRecipe
之间保持双向关系。这样,Envers可以正确地从任何一方查询适当的版本。
换句话说,将以下内容添加到CookieRecipe
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
private List<CookieRecipeBatch> batches = new ArrayList<>();
然后,您可以使用以下循环获取适当的版本化数据:
AuditReader reader = AuditReaderFactory.get( session );
for ( Number revision : reader.getRevisions(CookieRecipe.class, recipeId ) ) {
CookieRecipe recipe = reader.find( CookieRecipe.class, recipeId, revision );
// recipe.getSteps() - contains all steps with revision number <= revision
// recipe.getBatches() - contains all batches with revision number <= revision
}
上面应该为您提供特定版本的CookieRecipe
以及适当的批处理和步骤快照。