休眠枚举:初始化枚举代理

在Hibernate Envers中,无论设置了哪种抓取类型,实体的所有相关集合都会延迟加载。因此,当审核查询具有其他实体集合的实体(当然,这两个实体都经过审核)时,该集合最初是一个(在调试时可以看到)。SetProxy

那么,如何初始化该代理?使用没有效果(我怀疑是因为Hibernate和Envers使用不同的代理对象)。我知道我可以通过迭代其项来初始化集合,但这对我来说不是一个选择,因为我在实体中有多个集合,更不用说维护问题了。Hibernate.initialize()

我需要急切地初始化它们,因为我在稍后的Hibernate会话已经关闭(将域对象转换为dtos)时访问集合。

我使用的是Hibernate 3.5.6。


答案 1

显然,这是Hibernate Envers的一个开放问题。他们的JIRA中已经存在一个问题:https://hibernate.atlassian.net/browse/HHH-3552。随意投票,也许它会加快速度,当他们看到有些人希望解决这个问题时,;)

在 Envers 团队解决此问题之前,有一个适用于我的解决方法:调用集合会初始化代理对象。size()


答案 2

到目前为止,我发现的初始化Envers代理的最佳解决方法是使用Dozer。将 Envers 返回的已审核实体映射到自身,强制进行初始化。

例如:

    // Assuming you have an initialized EntityManager in entityManager & 
    // id contains your entity id..

    List<Object[]> auditList = (List<Object[]>)AuditReaderFactory.
                                   get(entityManager).
                                   createQuery().
                                   forRevisionsOfEntity(Foo.class, false, true).
                                   add(AuditEntity.id().eq(id)).
                                   getResultList();

    // Use a singleton in production apps instead...
    DozerBeanMapper mapper = new DozerBeanMapper();

    for(Object[] audit : auditList) {
        audit[0] = mapper.map(audit[0], Foo.class);
    }

    // The proxies in the Foo instances in auditList are now initialized

我对这个解决方案不是很满意,但我更喜欢它,而不是通过手动触摸集合来初始化代理。希望有人想出更好的替代方案,否则HHH-3552得到修复!


推荐