【问题标题】:Understanding Hibernate Fetch了解 Hibernate Fetch
【发布时间】:2011-06-13 09:53:24
【问题描述】:

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

当我运行我的查询并且从不使用对象时,休眠仍然会加入我的角色和游戏对象。所以我有3个查询。我知道我可以通过 fetch join 解决这个问题,但我的问题是为什么 hibernate 会同时获取两个实体?即使我用 fetch=FetchType.LAZY 注释它们,它也会被查询。

我的 DAO:

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

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

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    发生这种情况的原因是它们被标记为可为空。使用代理时,Hibernate 仍然需要知道要代理的对象和实际上只是纯 null 的对象之间的区别。

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

    如果您同时标记fetch=FetchType.LAZYoptional=false,您可以在onetoone 上获得懒惰。当然,如果实际列可以为空,那么您就是 SOL。

    【讨论】:

    • 啊,我现在更明白了,为什么我的案例没有延迟加载。感谢您的努力!
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-16
      • 2020-08-10
      • 2023-04-08
      • 2015-07-03
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      相关资源
      最近更新 更多