Fetchtype.LAZY具有相同的实体

时间:2017-01-26 12:13:07

标签: java jpa recursion spring-data

我构建了一个存储在数据库中的树结构。该关系构建在数据库表中的id,parent_id列上。我正在使用spring数据和休眠。

为了访问树结构,我构建了一个实体类" Node"和#34; NodeRepository"。实体类有一个属性" children"与自己有@OneToMany关系。

获取节点没问题。但是抓住孩子是一个问题,因为在事务环境之外的懒惰提取("未能懒惰地初始化角色集合")。

我将Fetchmode改为渴望。但这也是一个问题,因为它与自身的关系,它最终得到了整个树结构。

那么,在这种情况下,最好的做法是保持孩子们一方面的检索,而不是在另一侧取出整个结构?

4 个答案:

答案 0 :(得分:1)

我认为我有一个符合我需求的解决方案。

首先我定义了一个扩展我的NodeRepository接口的自定义接口,给它一个额外的方法“findOneWithChildrenInit”并实现它。

public interface NodeRepositoryCustom {

    public Node findOneWithChildrenInit(Long id);

}

public class NodeRepositoryImpl implements NodeRepositoryCustom {

    @Autowired
    NodeRepository repo;

    @Override
    @Transactional
    public Node findOneWithChildrenInit(Long id) {
        Node node = repo.findOne(id);
        node.getChildren().size();
        return node;
    }

}

所以我可以决定。当我不需要孩子时,我可以简单地调用findOne()。然后我需要它们,我调用findOneWithChildrenInit()。

答案 1 :(得分:0)

这可能取决于提供者的实现。但通常,当您以任何方式使用该集合时,都会初始化子集合。所以,一种常见的方法是在退出交易之前调用children.size(),然后扔掉结果。

答案 2 :(得分:0)

您仍然可以使用延迟提取类型,并确保在提取所有子项时该会话尚未关闭。你可以这么简单:

Session session = sessionFactory.openSession();
// fetch all required Nodes & all their children by using the same session object
session.close();

答案 3 :(得分:0)

如果您的实体中还有另外一个关系,则需要在其他eagers中包含注释@Fetch(FetchMode.SELECT)

在fetchmode中检查official documentation每个typer avaiables。