【发布时间】:2010-10-22 01:49:05
【问题描述】:
我有一个由 Hibernate 加载的实体(通过 EntityManager):
User u = em.load(User.class, id)
此类由 Hibernate Envers 审核。如何加载以前版本的用户实体?
【问题讨论】:
标签: java hibernate jboss hibernate-envers
我有一个由 Hibernate 加载的实体(通过 EntityManager):
User u = em.load(User.class, id)
此类由 Hibernate Envers 审核。如何加载以前版本的用户实体?
【问题讨论】:
标签: java hibernate jboss 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,但您必须调整它以适应您的环境。
【讨论】:
forRevisionsOfEntity(clazz,false,true) 返回带有实例、修订信息和修订类型的Objec[]?如何将其类型转换为Number?
也许是这样(来自AuditReader docs)
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));
(我对此很陌生,不确定我的语法是否正确,也许 size()-1 应该是 size()-2?)
【讨论】:
size()-2 才能获得倒数第二个修订版
user_rev1? reader.getRevisions 接受 primaryKey 作为第二个参数。不是实体。所以你只需要AuditReader reader = AuditReaderFactory.get(entityManager); List<Number> revNumbers = reader.getRevisions(User.class, user.getId()); User user_previous = reader.find(User.class, user.getId(), revNumbers.get(revNumbers.size()-1));
我想应该是这样的:
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);
【讨论】: