JPA / EclipseLink懒惰集合未加载

时间:2012-08-28 18:18:30

标签: java jpa lazy-loading eclipselink

我有一个具有此映射的用户实体:

@OneToMany(mappedBy = "supervisor", fetch = LAZY, cascade = [CascadeType.REFRESH])
List<Group> supervisedGroups = new ArrayList<Group>()

以及具有此映射的Group实体:

@ManyToOne(fetch = LAZY, cascade = [CascadeType.REFRESH])
@JoinColumn(name = "supervisor")
User supervisor

我感谢存储库

获取用户
User user = userRepository.findById(id)

findById方法由事务包装(方法由事务管理器通知拦截),JPA工作单元的持续时间与请求最后一次(每个视图的会话)。

当我收到用户时,我会做

user.getSupervisedGroups()

这会返回一个空列表。集合类型是Eclipselinks的IndirectList,即使我调用size()方法,它也不会做任何事情。

但是如果我执行

entitymanager.refresh(user)
user.getSupervisedGroups()

然后我列表中有2个项目......为什么?这是否意味着EclipseLink不支持对集合进行所有LAZY获取?

3 个答案:

答案 0 :(得分:2)

我的猜测是你破坏了共享二级缓存中的对象。

插入此对象时,是否将正确的对象添加到集合中?我的猜测是你有一个双向的OneToMany / ManyToOne关系,当插入One侧而不是添加到Many侧。您必须正确维护对象的关系。

请参阅, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

答案 1 :(得分:1)

将来自两个实体的获取属性 fetch = LAZY 更改为 fetch = FetchType.LAZY ;

  @OneToMany(mappedBy = "supervisor", fetch=FetchType.LAZY, cascade = CascadeType.REFRESH)

答案 2 :(得分:0)

詹姆斯的回答可能是问题的根源。另一种解决方案是禁用EclipseLinks L2缓存:

持久性单位属性:

<property name="eclipselink.cache.shared.default" value="false"/>

或JPA 2.0持久性单元元素:

<shared-cache-mode>NONE</shared-cache-mode>

来源:https://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F