2011-01-21 72 views
0

我知道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个查询。我知道我可以通过获取连接来解决这个问题,但是我的问题是为什么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(); 
    ... 

之前,我解决这个问题我想了解为什么会发生。 在此先感谢 m

回答

5

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

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

如果您同时标记fetch=FetchType.LAZYoptional=false,您可以在onetoone上进行懒读取。当然,如果实际列是可空的,那么你就是SOL。

+0

啊我明白这一点,现在更多的原因我的情况没有延迟加载。谢谢你的努力! – mkuff 2011-01-21 20:56:08