为了账号安全,请及时绑定邮箱和手机立即绑定

spring-data-jpa如何在特定的时候获取lazy加载的数据

spring-data-jpa如何在特定的时候获取lazy加载的数据

收到一只叮咚 2019-03-01 10:40:24
比如说我有两个实体EntityA, EntityB,是多对多关系,并且互相指定默认使用Lazy加载 @Entity public class EntityA implements Serializable { ... @ManyToMany(fetch = FetchType.LAZY) private List<EntityB> entityBList = new ArrayList<>(); ... } @Entity public class EntityB implements Serializable { ... @ManyToMany(mappedBy = "entityBList", fetch= FetchType.LAZY) private List<EntityA> entityAList = new ArrayList<>(); ... } 在做单元测试的时候,如果通过A获取B的List,会抛出LazyInitializationException @Test public void test() throws Exception { EntityA a = dao.findOne(id); List<EntityB> bList = a.getEntityBList(); bList.size(); // 这里抛出异常 } 如果在@Test下加上@Transactional倒是可以但是如果把find方法提出来作为一个新方法调用,则又不行了。。。 @Test public void test() throws Exception { this.getAwithLazyData(); } @Transactional public void getAwithLazyData(id) { EntityA a = dao.findOne(id); List<EntityB> bList = a.getEntityBList(); bList.size(); // 这里仍然抛出异常 } 当然,如果将fetch= FetchType.LAZY改为fetch= FetchType.EAGER是不会抛异常不过每次查询就都会带出关联数据了。。。但我只想在特定的时候带出关联数据,请问应该怎么处理。。。
查看完整描述

2 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

在找了一些资料之后,发现了一个解决方法,换了一个思考方向
该方法在spring-boot 1.5.6中测试通过

使用@NamedEntityGraph相关注解

Entity上:

@Entity
@NamedEntityGraph(name = "EntityA.lazy", attributeNodes = {@NamedAttributeNode("entityBList")})
public class EntityA implements Serializable {
    ...
    @ManyToMany(fetch = FetchType.LAZY)
    private List<EntityB> entityBList = new ArrayList<>();
    ...
}

对应的Dao上:

@Repository
public interface EntityADao extends SimpleJpaRepository<EntityA, Long> {
    @EntityGraph(attributePaths = { "entityBList" })
    EntityA findWithEntityBById(Long id);
}

这样,如果调用的是原本的findOne方法,则查询结果中的entityBList为lazy数据,无法取出。
如果调用findWithEntityBById方法,则查询结果中已经带出了entityBList,可以直接使用。

不知道有没有更好的方案。

查看完整回答
反对 回复 2019-03-01
?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

我觉得是session过期的原因,你试试不用JPA findOne 查询,改用手写hql,session.query() 试试看。

查看完整回答
反对 回复 2019-03-01
  • 2 回答
  • 0 关注
  • 1314 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信