【发布时间】:2015-04-28 11:00:27
【问题描述】:
今天我学习了一个教程,作者解释了休眠关联一对多/多对一。 我不想在这里写他所有的代码。所以,我试着专注于主要......
我们有两个实体:“Team”和“Player”
在我们的代码中:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="team_id")
private Team team;
和
@OneToMany(mappedBy="team", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Player> players;
我感兴趣的主要是获取类型。所以,我们插入了一个team和一些属于这个team的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()));
这是正确的解决方案吗?我应该在实际开发中使用哪一个?
还有一个问题。在我初始化玩家集合后(无论我使用哪种解决方案),我都可以获得其中一个。好的,并且在“玩家”实体字段中,团队将初始化。为什么?而这支队伍将拥有玩家的收藏……我们有循环依赖……这正常吗?
【问题讨论】:
-
您是否在
sessionFactory.getCurrentSession().get(team, id);行之后关闭了Hibernate 会话?会话还活着吗? -
我使用 Spring,我希望 Spring 框架会负责关闭会话。还是我错了?
-
我不知道你用的是哪种弹簧配置。但根据我对
team.getPlayers();调用之前的理解,会话可能已经关闭并且团队对象与会话分离。这可能是此错误的原因。如果你尝试从分离的对象延迟加载,那么你会得到这种错误。 -
Anchit Pancholi 谢谢。你说的对。会话可能在
get(team, id)之后关闭。当我打电话给team.getPlayers()之后,我得到了 LazyInitializationException 因为我设置了fetch = FetchType.LAZY而不是fetch = FetchType.EAGER。我不反对这个事实。这很正常......我问了关于手动初始化玩家收藏的问题:使用方法initialize()或HQL。你更喜欢哪一个?
标签: java hibernate fetch lazy-initialization