了解Hibernate Fetch

时间:2011-01-21 20:43:59

标签: java hibernate jpa

我知道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();
  ...

在我解决这个问题之前,我想了解它为什么会发生。 提前致谢 米

2 个答案:

答案 0 :(得分:5)

它发生的原因是它们被标记为可空。当使用代理时,Hibernate仍然需要知道代理和实际上只是普通的那些之间的区别。

当关系是一个集合时,它可以为您提供一个空集合,然后再检查。但是当它是OneToOne时,它必须查看数据库,以确定该字段是否应该为空,或者它是否可以被代理和延迟加载。因为它无论如何都要看,它只是加载它。

如果您同时标记fetch=FetchType.LAZYoptional=false,则可以对onetoone进行延迟抓取。当然,如果列实际可以为空,那么你就是SOL。

答案 1 :(得分:0)