Hibernate is using wrong table name for order by expression with three level inheritance

后端 未结 1 750
一个人的身影
一个人的身影 2021-02-12 21:12

In our project we have different user types presented by different classes. And we have a BaseEntity class as @MappedSuperclass. When we try to use user classes with Inheritanc

1条回答
  •  南笙
    南笙 (楼主)
    2021-02-12 21:51

    I replicated your test case, you can find it on GitHub.

    There must be a Hibernate bug, because when you use the alias, the select clause uses the subclass ID, while the ORDER BY uses the base class id, which since it's not in the select clause, throws an exception:

    SELECT inheritanc0_.id             AS ID1_0_,
           inheritanc0_1_.created_date AS CREATED_2_0_,
           inheritanc0_.NAME           AS name1_1_
    FROM   firm_user inheritanc0_
           INNER JOIN base_user inheritanc0_1_
                   ON inheritanc0_.id = inheritanc0_1_.id
    ORDER  BY inheritanc0_1_.id 
    

    Notice the ORDER BY inheritanc0_1_.id, it should have been ORDER BY inheritanc0_.id instead.

    Workaround 1:

    Rewrite the query without alias:

    List result1 = (List) session.createQuery("from FirmUser order by id").list(); 
    

    The SQL being properly generated:

    SELECT inheritanc0_.id             AS ID1_0_,
           inheritanc0_1_.created_date AS CREATED_2_0_,
           inheritanc0_.NAME           AS name1_1_
    FROM   firm_user inheritanc0_
           INNER JOIN base_user inheritanc0_1_
                   ON inheritanc0_.id = inheritanc0_1_.id
    ORDER  BY inheritanc0_1_.id 
    

    Workaround 2:

    or specifying the subclass.id as well, but that results in an array of subclass and subclass entity tuples:

    List result2 = (List) session.createQuery("select distinct a, a.id from FirmUser a order by id").list();
    

    Giving the following SQL:

    SELECT DISTINCT inheritanc0_1_.id           AS col_0_0_,
                    inheritanc0_1_.id           AS col_1_0_,
                    inheritanc0_.id             AS ID1_0_,
                    inheritanc0_1_.created_date AS CREATED_2_0_,
                    inheritanc0_.NAME           AS name1_1_
    FROM   firm_user inheritanc0_
           INNER JOIN base_user inheritanc0_1_
                   ON inheritanc0_.id = inheritanc0_1_.id
    ORDER  BY inheritanc0_1_.id 
    

    Workaround 3:

    Like always, a native query gives you the ultimate control over any tuple association:

    List result3 = (List) session.createSQLQuery(
            "select * " +
            "from FIRM_USER a " +
            "LEFT JOIN BASE_USER b ON a.id = b.id " +
            "order by a.id"
    )
    .addEntity("a", FirmUser.class)
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    .list();
    

    You should fill a Hibernate issue for this problem, as it's not behaving as it should be.

    0 讨论(0)
提交回复
热议问题