我知道hibernate是懒惰的默认抓取策略,但有一些事情我不清楚,所以我希望你能解释一下。我想要做的是将标记为标记为起始图块的图块。
查询:
@NamedQuery(name = "Tile.findStartTileByGame",
query = "SELECT t FROM Tile t WHERE t.game = :game " +
"and t.startTile = true and t.blockWalkable = false")
瓷砖:
public class Tile{
@OneToOne(mappedBy="tile")
private GameCharacter character;
@OneToOne(mappedBy="tile")
private GameObject gameObject;
游戏:
@OneToMany(mappedBy="game")
private List<Tile> tiles;
当我运行我的查询并且从不使用该对象时,hibernate仍然加入了我的角色和游戏对象。所以我有3个查询。我知道我可以通过fetch join来解决这个问题,但我的问题是为什么hibernate会同时获取两个引用?即使我用fetch = FetchType.LAZY对它们进行注释,也会被查询。
我的道:
public static Tile getFreeStartTile(EntityManager em, Game game) {
TypedQuery<Tile> query = em.createNamedQuery("Tile.findStartTileByGame", Tile.class);
query.setParameter("game", game);
List<Tile> result = query.getResultList();
...
在我解决这个问题之前,我想了解它为什么会发生。 提前致谢 米
答案 0 :(得分:5)
它发生的原因是它们被标记为可空。当使用代理时,Hibernate仍然需要知道代理和实际上只是普通的那些之间的区别。
当关系是一个集合时,它可以为您提供一个空集合,然后再检查。但是当它是OneToOne
时,它必须查看数据库,以确定该字段是否应该为空,或者它是否可以被代理和延迟加载。因为它无论如何都要看,它只是加载它。
如果您同时标记fetch=FetchType.LAZY
和optional=false
,则可以对onetoone进行延迟抓取。当然,如果列实际可以为空,那么你就是SOL。
答案 1 :(得分:0)