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

╄→尐↘猪︶ㄣ 提交于 2019-12-03 10:57:53

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<FirmUser> result1 = (List<FirmUser>) 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<Object[]> result2 = (List<Object[]>) 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<FirmUser> result3 = (List<FirmUser>) 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!