我构建了一个存储在数据库中的树结构。该关系构建在数据库表中的id,parent_id列上。我正在使用spring数据和休眠。
为了访问树结构,我构建了一个实体类" Node"和#34; NodeRepository"。实体类有一个属性" children"与自己有@OneToMany关系。
获取节点没问题。但是抓住孩子是一个问题,因为在事务环境之外的懒惰提取("未能懒惰地初始化角色集合")。
我将Fetchmode改为渴望。但这也是一个问题,因为它与自身的关系,它最终得到了整个树结构。
那么,在这种情况下,最好的做法是保持孩子们一方面的检索,而不是在另一侧取出整个结构?
答案 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。