2017-08-16 50 views
0

所以这里是我的问题:休眠 - 实体的投影和取物策略

我有2个人类和部门。

人:

@Entity 
public class Personne 
{ 
    @Id 
    private Long id; 

    private String name; 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="dept_id") 
    @Fetch(FetchMode.JOIN) 
    private Departement dept; 


    // getter & setter 
} 

部:

@Entity 
public class Departement 
{ 
    @Id 
    private Long id; 

    private String name; 

    // getter & setter 

} 

我想选择一个personn只DEPARTEMENT与条件查询,所以我使用的投影:

我代码:

Criteria crt = session.createCriteria(Personne.class); 
      crt.createAlias("dept", "d",JoinType.LEFT_OUTER_JOIN); 
      crt.setProjection(Projections.projectionList().add(Projections.property("dept"))); 
      crt.add(Restrictions.eq("id", 1L)); 

以上查询效果很好,但我得到2个查询,而我期望只有1,因为我的提取类型是渴望。

日志:

[use] 2017-08-16 16:23:07,113 DEBUG [main] SqlStatementLogger.logStatement(109) | select this_.dept_id as y0_ from Personne this_ left outer join Departement d1_ on this_.dept_id=d1_.id where this_.id=? 
[use] 2017-08-16 16:23:07,119 DEBUG [main] SqlStatementLogger.logStatement(109) | select departemen0_.id as id1_0_0_, departemen0_.name as name2_0_0_ from Departement departemen0_ where departemen0_.id=? 

似乎实体火灾n + 1个选择的那个投影。那有意义吗?

任何人都可以帮助我吗?

感谢

+0

我认为你必须做一个系统输出或者在强制休眠来触发第二个查询的条件执行之后做别的事情。你可以在session.createCriteria(...)方法之后显示完整的代码吗? –

+0

@MadhusudanaReddySunnapu,你的回复,不,我只是'crt.list();'这个代码后没有更多。 –

+0

如果您在映射上删除了@ @CollectionColumn和@Fetch'注解,会发生什么? – Naros

回答

0

EAGER并不意味着更少的查询将被执行,只有当业主实体被查询的查询将被执行。

你可以使用的是@FetchMode注释,在你的情况下,我会假设你想要一个FetchMode.JOIN

FechtMode的javadoc:https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/FetchMode.html

无论哪种方式,要小心的结果,请他深入讨论了如何抓取模式工作检查从FetchMode Join vs SubSelect的gabrielgiussi答案。

+0

谢谢你的回复,但是我已经在FetchMode.JOIN中使用了@FetchMode注解,并且我期待它在获取personn的时候获得一个外连接,但它不会。 –

+0

哦对不起,我的错误,我完全误解了它 –

+0

但是,如果你已经有获取类型和一切,你不需要做crt.setProjection(Projections.projectionList()。add(Projections)。财产(“部”))),它将已经带来的查询 –