今天我学习了一篇教程,作者解释了 hibernate 关联一对多/多对一。 我不想把他的所有代码都写在这里。所以,我尝试专注于主要...
我们有两个实体:“团队”和“玩家”
在代码中我们有:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="team_id")
private Team team;
和
@OneToMany(mappedBy="team", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Player> players;
我感兴趣的主要是获取的类型。因此,我们插入了一个团队和一些属于该团队的玩家。 我的 DAO 类标有
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
现在我想从数据库加载团队实体,其中包含填充的玩家集合。
Team team = new Team();
sessionFactory.getCurrentSession().get(team, id);
//and after somewhere in code
team.getPlayers();
结果我会得到LazyInitializationException
。这显然是……
我们可以解决这个问题:
Hibernate.initialize(team.getPlayers());
或者我们可以使用 HQL 加载玩家集合。我的意思是:
Query query = currentSession().createQuery("from Player p where p.team.id =:id");
query.setParameter("id",key);
team.setPlayers(new HashSet(query.list()));
这是正确的解决方案吗?在实际开发中我应该使用其中哪一个?
还有一个问题。在我初始化玩家集合后(无论我使用哪种解决方案),我都可以获得其中一个。好的,在“玩家”实体字段中,团队将初始化。为什么?这个团队将充满玩家的 Collection ...我们有循环依赖...这正常吗?
最佳答案
当 session 关闭并且您尝试从分离的对象加载惰性对象时,会出现 LazyInitializationException。这里的团队是分离的对象(因为 session 可能在此调用之前关闭)并尝试加载惰性对象玩家。
对于这种问题需要使用哪种方法,这取决于您的要求。如果您在每个代理上调用 Hibernate.initialize,则每次调用都会生成一个查询。
下面您正在使用联合:-
Query query = currentSession().createQuery("from Player p where p.team.id =:id");
这只需要一次查询,我认为如果您查询大量数据,您应该使用这种方法。
有关更多信息,请查看this link .
关于java - hibernate 获取懒惰: Initialize() or HQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29917564/