考虑这些课程:
@Audited
@Entity
public class Child
{
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
@JoinColumn(nullable = false)
private Father father;
private String name;
}
@Audited
@Entity
public class Father
{
@Id
@GeneratedValue
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private Set<Child> children;
public void addChild(Child child)
{
if (null == this.children)
this.children = new HashSet<>();
this.children.add(child);
}
private String name;
}
创建子项和父项时,映射正确完成。建立关系后,不会在AuditedJoinColumn中更新子项名称。
因此在此测试之后:
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.AuditQuery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
public class BasicTest
{
private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("EnversTest");
private Long fatherId;
private Long childId;
@Before
public void setup()
{
EntityManager em = emf.createEntityManager();
try
{
em.getTransaction().begin();
Father father = new Father();
father.setName("Dad");
Child child = new Child();
child.setName("Sam");
child.setFather(father);
father.addChild(child);
em.persist(child);
em.persist(father);
em.getTransaction().commit();
this.fatherId = father.getId();
this.childId = child.getId();
/////// Change child's name ///////
em.getTransaction().begin();
child.setName("John");
em.persist(child);
em.getTransaction().commit();
}
finally
{
em.close();
}
}
@Test
public void validateChildForAllRevisions()
{
EntityManager em = emf.createEntityManager();
try
{
{ // assert there are 2 revision of child
List<Object[]> changes = getAllRevisions(Child.class, childId, em);
assertNotNull(changes);
assertEquals(2, changes.size());
assertEquals("Sam", ((Child)changes.get(0)[0]).getName());
assertEquals("John", ((Child)changes.get(1)[0]).getName());
}
{ // assert there is 1 revision of father
List<Object[]> changes = getAllRevisions(Father.class, fatherId, em);
assertNotNull(changes);
assertEquals(1, changes.size());
// make sure latest father has a child named John
Father lastRevOfFather = (Father)changes.get(0)[0];
assertNotNull(lastRevOfFather);
assertNotNull(lastRevOfFather.getChildren());
assertEquals(1, lastRevOfFather.getChildren().size());
for (Child auditedChild : lastRevOfFather.getChildren())
assertEquals("John", auditedChild.getName());
}
}
finally
{
em.close();
}
}
@Test
public void validateChildNameAtSpecificRevision()
{
EntityManager em = emf.createEntityManager();
try
{
Date time = new Date();
List<Object[]> changes = getLastRevision(Father.class, fatherId, em, time);
assertNotNull(changes);
assertEquals(1, changes.size());
Father auditedFather = (Father)changes.get(0)[0];
assertNotNull(auditedFather);
assertNotNull(auditedFather.getChildren());
assertEquals(1, auditedFather.getChildren().size());
for (Child auditedChild : auditedFather.getChildren())
assertEquals("John", auditedChild.getName());
}
finally
{
em.close();
}
}
public List<Object[]> getAllRevisions(final Class clazz, final Long entityId, EntityManager em)
{
AuditReader reader = AuditReaderFactory.get(em);
AuditQuery query = reader.createQuery().forRevisionsOfEntity(clazz, false, false);
query.add(AuditEntity.id().eq(entityId));
return query.getResultList();
}
public List<Object[]> getLastRevision(final Class clazz, final Long entityId, EntityManager em, final Date time)
{
AuditReader reader = AuditReaderFactory.get(em);
Number rev = reader.getRevisionNumberForDate(time);
AuditQuery query = reader.createQuery().forRevisionsOfEntity(clazz, false, false);
query.add(AuditEntity.id().eq(entityId));
query.add(AuditEntity.revisionNumber()
.maximize()
.add(AuditEntity.revisionNumber().le(rev))
.computeAggregationInInstanceContext());
return query.getResultList();
}
@After
public void cleanup()
{
EntityManager em = emf.createEntityManager();
try
{
em.getTransaction().begin();
em.remove(em.find(Father.class, fatherId));
em.getTransaction().commit();
}
finally
{
em.close();
}
}
}
子名称比较断言失败: org.junit.ComparisonFailure:expected:&lt; [John]&gt;但是:&lt; [Sam]&gt;
到目前为止,我认为强制重新映射的唯一方法是改变父亲的某些东西。
我希望有更好的方法来做到这一点。