2017-01-10 66 views
1

我定义如下JPA - EntityGraph和Hibernate的L2 Cache(ehcache的)

@Cacheable 
@Entity 
@NamedEntityGraph(
    name = "Parent.Child", 
    attributeNodes = { 
     @NamedAttributeNode("children"), 
    } 
) 
public class Parent { 
    private Set<Child> children; 
    // getter - setter 
} 

现在在我的DAL一个一对多的关系,我调用此方法

@Override 
    public Parent getParentWithChildren(int id) { 
     EntityGraph<?> graph = entityManager.getEntityGraph("Parent.Child"); 
     Map<String, Object> props = new HashMap<>(); 
     props.put("javax.persistence.fetchgraph", graph); 
     return entityManager.find(Parent.class, id, props); 
    } 

由于我已经加载了父母与子女,我应该可以使用子女收集交易之外。但我得到懒惰初始化异常。只有在启用休眠级别2缓存 - ehcache时才会发生这种情况。如果我从配置中禁用它,它按预期工作。此外,如果我找到后明确初始化收集,它按预期工作。那么这是一个错误?我正在使用Hibernate 5.2.6.Final和JPA 2.1。

编辑:我还注意到的一件事是,实体首次加载罚款,所以这个问题必须与休眠&缓存提供程序有关。

+0

我遇到类似的情况。我不使用二级缓存。我意识到,如果实体已经在持久化上下文中,那么使用fetchgraph提示的下一个em.find不会加载数据库中的任何内容。在我看来,这也是bug。 – srnjak

+0

我认为会话缓存也是如此。这是一个确认的错误,它被标记为在5.2.10 – user2578525

回答

0

不,这不是一个错误。我猜Hibernate会延迟从缓存加载直到真正需要。除非您要求提前获取,否则实现可能会认为是合适的。

所以一般的规则是在离开事务之前加载你需要的所有东西(在关闭Hibernate会话之前要精确)。

+0

中解决我已经在使用获取图来急切地加载子集合 – user2578525

+0

您没有给我足够的信息来证明它,但我怀疑它实际上是代理中的对象被延迟加载。 – Henri

+1

查看道具对象。我指定获取图形 – user2578525