ResultTransformer deprecated 替代方案及HQL無法使用子查詢解決

hibernate 由於從5.2升級成5.4 再用了ResultTransformer封裝臨時對象時sonar 報錯,顯示ResultTransformer 過時

在這裏插入圖片描述

官方在5.2版本中將此方法標記爲過時,但沒有提供替代方案,需要升級到6.0時才提供提到方法

雖然ResultTransformer方法過時,但接口並沒有,我們可以通過內部類的方式實現自定義封裝。

List<PersonAndCountryDTO> personAndAddressDTOs = entityManager
.createQuery(
    "select p, c.name " +
    "from Person p " +
    "join Country c on p.locale = c.locale " +
    "order by p.id")
.unwrap( org.hibernate.query.Query.class )
.setResultTransformer(
    new ResultTransformer() {
        @Override
        public Object transformTuple(
            Object[] tuple,
            String[] aliases) {
            return new PersonAndCountryDTO(
                (Person) tuple[0],
                (String) tuple[1]
            );
        }
 
        @Override
        public List transformList(List collection) {
            return collection;
        }
    }
)
.getResultList();

不實現該接口我們可以通過HQL 的方式實現封裝:
在這裏插入圖片描述

但由於hql 總不支持子查詢 生成的虛表必須有對應的實體類跟映射文件纔可,不然會報如下異常:

org.hibernate.hql.internal.ast.QuerySyntaxException:
 unexpected token: ( near line 1, column 136 
 [SELECT new com.gravity.dao.job.JobStatusAlertItem(j.id, j.clientId, c.lastHiredTime)  
 FROM com.gravity.model.job.JobPO AS j 
 INNER JOIN ( 
	SELECT ce.jobId, COUNT(ce.candidateId) AS hiredNum, MAX(ce.changedTime)*1000 AS lastHiredTime  
	FROM com.gravity.model.analytic.CandidateHireOrBackBurnerEventsPO AS ce 
	WHERE ce.status=60  
	AND ce.candidateId NOT IN ((SELECT cd.id FROM com.gravity.model.candidate.CandidateDeletedPO AS cd)) GROUP BY ce.jobId
) AS c ON c.jobId = j.id  WHERE j.status = 2 AND j.noOfOpenings <= c.hiredNum  AND j.confidential IS FALSE AND j.candidatePool IS FALSE]

最後 只能使用 list<Object[]> 接收收據。

參考: https://vladmihalcea.com/why-you-should-use-the-hibernate-resulttransformer-to-customize-result-set-mappings/

HQL中使用子查詢解決方法: https://blog.csdn.net/fableking/article/details/3167081

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章