[英]Get previous version of entity in Hibernate Envers
我有一個由Hibernate加載的實體(通過EntityManager
):
User u = em.load(User.class, id)
該課程由Hibernate Envers審核。 如何加載以前版本的用戶實體?
這是另一個版本,它找到相對於“當前”版本號的先前版本,因此即使您正在查看的實體不是最新版本,也可以使用它。 它還處理沒有事先修訂的情況。 (假設em
是以前填充的EntityManager)
public static User getPreviousVersion(User user, int current_rev) {
AuditReader reader = AuditReaderFactory.get(em);
Number prior_revision = (Number) reader.createQuery()
.forRevisionsOfEntity(User.class, false, true)
.addProjection(AuditEntity.revisionNumber().max())
.add(AuditEntity.id().eq(user.getId()))
.add(AuditEntity.revisionNumber().lt(current_rev))
.getSingleResult();
if (prior_revision != null)
return (User) reader.find(User.class, user.getId(), prior_revision);
else
return null
}
這可以推廣到:
public static T getPreviousVersion(T entity, int current_rev) {
AuditReader reader = AuditReaderFactory.get(JPA.em());
Number prior_revision = (Number) reader.createQuery()
.forRevisionsOfEntity(entity.getClass(), false, true)
.addProjection(AuditEntity.revisionNumber().max())
.add(AuditEntity.id().eq(((Model) entity).id))
.add(AuditEntity.revisionNumber().lt(current_rev))
.getSingleResult();
if (prior_revision != null)
return (T) reader.find(entity.getClass(), ((Model) entity).id, prior_revision);
else
return null
}
這種泛化的唯一棘手的一點是獲得實體的id。 因為我正在使用Play! 框架,我可以利用所有實體都是模型並使用((Model) entity).id
獲取id的事實,但你必須調整它以適應你的環境。
也許這就是(來自AuditReader文檔)
AuditReader reader = AuditReaderFactory.get(entityManager);
User user_rev1 = reader.find(User.class, user.getId(), 1);
List<Number> revNumbers = reader.getRevisions(User.class, user_rev1);
User user_previous = reader.find(User.class, user_rev1.getId(),
revNumbers.get(revNumbers.size()-1));
(我對此非常新,不確定我是否擁有正確的語法,也許大小() - 1應該是size() - 2?)
我想是這樣的:
final AuditReader reader = AuditReaderFactory.get( entityManagerOrSession );
// This could probably be declared as Long instead of Object
final Object pk = userCurrent.getId();
final List<Number> userRevisions = reader.getRevisions( User.class, pk );
final int revisionCount = userRevision.size();
final Number previousRevision = userRevisions.get( revisionCount - 2 );
final User userPrevious = reader.find( User.class, pk, previousRevision );
基於@ brad-mace的出色方法,我做了以下更改:
所以這是另一個解決方案:
public static <T> T getPreviousRevision(EntityManager entityManager, Class<T> entityClass, Object entityId, int currentRev) {
AuditReader reader = AuditReaderFactory.get(entityManager);
List<Object[]> priorRevisions = (List<Object[]>) reader.createQuery()
.forRevisionsOfEntity(entityClass, false, false)
.add(AuditEntity.id().eq(entityId))
.add(AuditEntity.revisionNumber().lt(currentRev))
.addOrder(AuditEntity.revisionNumber().desc())
.setMaxResults(1)
.getResultList();
if (priorRevisions.size() == 0) {
return null;
}
// The list contains a single Object[] with entity, revinfo, and type
return (T) priorRevision.get(0)[0];
}
來自文檔:
AuditReader reader = AuditReaderFactory.get(entityManager);
User user_rev1 = reader.find(User.class, user.getId(), 1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.