今天我学到了一个教程,其中作者解释了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 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()));
这是正确的解决方案吗?我应该在实际开发中使用哪些?
还有一个问题。在我初始化了玩家的收集后(无论我使用哪种解决方案),我都可以获得其中一个。好的,在#34;播放器&#34;实体字段团队将初始化。为什么?这个团队将与填充玩家的收藏......我们有循环依赖...这是正常的吗?
答案 0 :(得分:2)
LazyInitializationException在会话关闭并且您尝试从分离的Object加载延迟对象时出现。这里团队是分离对象(因为会话可能在此调用之前已关闭)并尝试加载惰性对象播放器。
关于哪种方法需要用于此类问题,这取决于您的要求。如果在每个代理上调用Hibernate.initialize,则每次调用都会生成一个查询。
在下面你使用联合: -
Query query = currentSession().createQuery("from Player p where p.team.id =:id");
这只需要一个查询,我认为如果你查询大量数据,你应该使用这种方法。
有关详细信息,请查看this link。