Hibernate - 实体的预测和获取策略

时间:2017-08-16 14:20:48

标签: hibernate hibernate-criteria

所以这是我的问题:

我有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

}

我想只选择一个具有标准查询的人员部门,所以我使用投影:

我的代码:

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选择。那有意义吗?

任何人都可以帮我这个吗?

由于

1 个答案:

答案 0 :(得分: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答案,因为他详细了解了获取模式的工作原理。