Hibernate(24): 为什么用DetachedCriteria不能表连接地取数据?

    HQL到DetachedCriteria的转换? 中是项目中实际问题描述, 这里用一个独立的例子来模拟项目中的问题,也基于此做debug跟踪.

     例子中有两个类: Husband和Wife,在Husband类里对Wife做了OneToOne关联. 代码和基于Annotation的映射配置如下:

@Entity
public class Husband {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Integer id;
    private String name;
   
    @OneToOne(fetch=FetchType.LAZY)  // (1)
    @JoinColumn(name="wife_id", nullable=false,unique=true)
    private Wife wife;

    

@Entity
public class Wife {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Integer id;
    private String name;
 


    更详细的类文件与基于Mysql的建表及数据见附件.

 配置好后, 做如下实验:
    1, 直接用如下HQL
        "select h.wife from Husband h where h.id = :id"
取数据, 没问题,只取出了对应Wife类的信息. Hibernate生成的SQL语句如下:
          select wife1_.id as id1_, wife1_.name as name1_ from Husband husband0_ inner join Wife wife1_ on husband0_.wife_id=wife1_.id where husband0_.id=?
     从上面生成SQL来看, Hibernate做了表连接查询,结果集中也只有Wife类信息.

    2,  用如下所示的DetachedCriteria取数据:
        DetachedCriteria.forClass(Husband.class)
            .add(Property.forName("id").eq(1))
            .setProjection(Property.forName("wife").as("wifeAlias"))
            .setFetchMode("wifeAlias", FetchMode.JOIN)  //(2)
            .setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);

        从运行结果看, 正确的Wife信息取出来了. 不过看相应的SQL,发现有此不对.
        Hibernate生成并执行的SQL如下:
            select this_.wife_id as y0_ from Husband this_ where this_.id=?
            select wife0_.id as id1_0_, wife0_.name as name1_0_ from Wife wife0_ where wife0_.id=?

        也就是说, Hibernate并没有做表连接查询,而采用的是二次查询,即从Husband表里得出相应的wife ID,再到Wife表里去取Wife信息. 这样虽说项目中的问题解决了(后来发现并没有解决,详见下一篇:Eclipse的debug欺骗了我), 但与上面红色标志的(2)处的设置不对. (2)处设置的FetchMode为JOIN,为什么不做表连接查询呢?

    3, 在上面红色标志(2)处,改为FetchMode.EAGER还是行. 还是二次查询,并没有像用HQL那样一次表连接地取出数据来.

    4, 只是作为一种可能性的试试,在上面红色标志(1)处,改为fetch=FetchType.EAGER,与实验3结果一样.


    这里把围绕这个问题的实验,记录下来,一是希望引起大家的讨论,二是作为自己的一个备忘并在此基础上做进一步研究.

你可能感兴趣的:(eclipse,sql,mysql,Hibernate)