2016-11-19 21 views
0

下面是該查詢例如,我執行javax.persistence.Query不設置參數

entityManager.createNativeQuery(SHIPMENTS_UNION_QUERY, RESULT_MAPPER) 
       .setParameter("aggreagateCategories", aggregatePCNames) 
       .setParameter("startDate", startDate) 
       .setParameter("endDate", endDate) 
       .setParameter("individualCategories", individualPCNames) 
       .getResultList(); 

的日誌,上面一行的執行是

12:29:36.909 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [3] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [6] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 'AirConditioner' -> aggreagateCategories [1] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [2] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [5] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 'Cooler', 'Heater', 'Dryer' -> individualCategories [4] 

當上述查詢執行param硬編碼到查詢本身,查詢執行得很好,結果被提取並映射到對應於@SqlResultSetMapping的RESULT_MAPPER,但是當使用上述setParameter語句完成時,執行不會返回任何結果..

請幫助確定問題。

EDIT1

硬編碼查詢

SELECT ac.category_name category_name, SUM(ais.volume) volume, qc.date, qc.quarter as quarter, qc.year 
FROM actual_industry_shipment ais 
JOIN quarter_calendar qc ON ais.quarter=qc.id 
JOIN product_category pc ON ais.product_category_id=pc.id 
JOIN aggregated_product_categories ac ON ac.id = pc.aggregate_category_id 
WHERE ac.category_name IN ('AirConditioner') 
AND qc.date BETWEEN '2010-01-01' AND '2011-01-01' 
GROUP BY pc.aggregate_category_id, qc.quarter, qc.year 
UNION 
SELECT pc.category_name category_name, ais.volume volume, qc.date, qc.quarter as quart, qc.year 
FROM actual_industry_shipment ais 
JOIN quarter_calendar qc ON ais.quarter=qc.id 
JOIN product_category pc ON ais.product_category_id=pc.id 
WHERE pc.category_name IN ('Dryer', 'Cooler') 
AND qc.date BETWEEN '2010-01-01' AND '2011-01-01' 

使用參數查詢

SELECT ac.category_name category_name, SUM(ais.volume) volume, qc.date, qc.quarter as quarter, qc.year 
FROM actual_industry_shipment ais 
JOIN quarter_calendar qc ON ais.quarter=qc.id 
JOIN product_category pc ON ais.product_category_id=pc.id 
JOIN aggregated_product_categories ac ON ac.id = pc.aggregate_category_id 
WHERE ac.category_name IN (?) 
AND qc.date BETWEEN ? AND ? 
GROUP BY pc.aggregate_category_id, qc.quarter, qc.year 
UNION 
SELECT pc.category_name category_name, ais.volume volume, qc.date, qc.quarter as quart, qc.year 
FROM actual_industry_shipment ais 
JOIN quarter_calendar qc ON ais.quarter=qc.id 
JOIN product_category pc ON ais.product_category_id=pc.id 
WHERE pc.category_name IN (?) 
AND qc.date BETWEEN ? AND ? 
即在代碼中聲明

原生查詢

private static final String SHIPMENTS_UNION_QUERY = 
     "SELECT ac.category_name category_name, SUM(ais.volume) volume, qc.date, qc.quarter as quarter, qc.year " + 
       "FROM actual_industry_shipment ais " + 
       "JOIN quarter_calendar qc " + 
       "ON ais.quarter=qc.id " + 
       "JOIN product_category pc " + 
       "ON ais.product_category_id=pc.id " + 
       "JOIN aggregated_product_categories ac " + 
       "ON ac.id = pc.aggregate_category_id " + 
       "WHERE " + 
       "ac.category_name IN (:aggreagateCategories) " + 
       "AND qc.date BETWEEN :startDate AND :endDate " + 
       "GROUP BY " + 
       "pc.aggregate_category_id, qc.quarter, qc.year " + 

       "UNION " + 

       "SELECT pc.category_name category_name, ais.volume volume, qc.date, qc.quarter as quart, qc.year " + 
       "FROM actual_industry_shipment ais " + 
       "JOIN quarter_calendar qc " + 
       "ON ais.quarter=qc.id " + 
       "JOIN product_category pc " + 
       "ON ais.product_category_id=pc.id " + 
       "WHERE pc.category_name IN (:individualCategories) " + 
       "AND qc.date BETWEEN :startDate AND :endDate"; 
+0

您可以添加代碼SHIPMENTS_UNION_QUERY以及其導致了問題? – developer

+0

請發佈您嘗試執行的查詢。 –

+0

發現問題,我一直髮送參數到IN子句作爲引用文本,而不是列表中的setParameter,但它僅在休眠支持 –

回答

0

命名PARAMS查詢是不完全相同的原始硬編碼原生SQL查詢,你可以看看下面(採取只遞延節查詢):

參數查詢:

category_name, ais.volume volume, qc.date, 
qc.quarter as quart, qc.year FROM 
actual_industry_shipment ais 
JOIN quarter_calendar qc ON 

硬編碼查詢:

ais.quarter=qc.id JOIN category_name, 
ais.volume volume, product_category pc ON ais.product_category_id=pc.id WHERE 
pc.category_name IN ('Dryer', 'Cooler') AND qc.date 
BETWEEN '2010-01-01' AND '2011-01-01' 
+0

我使用命名參數,添加一個更新 –

+0

請現在檢查 –

+0

JPA不要求實現支持本機查詢中的命名參數,但Hibernate將其作爲獎勵功能。如果OP切換到EclipseLink,它將不起作用,但這不是問題。 – coladict

0

您的日期參數作爲硬編碼的查詢似乎是不綁定的字符串和工作,而且同一天在兩個應用開始,從硬編碼的結束日期不同查詢。

12:29:36.909 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [3] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [6] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 'AirConditioner' -> aggreagateCategories [1] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [2] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [5] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 'Cooler', 'Heater', 'Dryer' -> individualCategories [4] 

您的查詢這是工作有特定日期的報價,

BETWEEN '2010-01-01' AND '2011-01-01' 
+0

你幾乎擁有它。他將同一日期綁定到startDate和endDate。我的同事做了同樣的事情,沒有意識到他必須使用一個新的java.util.Date對象來設置這兩個參數,而不是重用它並調用setYear或任何OP正在使用的參數。他所做的是'Date endDate = startDate; endDate.setMonth(...);'然後綁定它。我認爲我的OP必須做同樣的事情,沒有意識到endDate和startDate是相同的對象,而不是對方的副本。 – coladict

+0

@coladict我的接球能夠被接受嗎? – ScanQR

0

這是我們看到的問題:

12:29:36.909 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [3] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> endDate [6] 
12:29:36.910 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 'AirConditioner' -> aggreagateCategories [1] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [2] 
12:29:36.912 DEBUG org.hibernate.loader.Loader : bindNamedParameters() 2010-01-01 -> startDate [5] 

你要綁定兩個相同的日期。 我猜你的代碼看起來是這樣的:

Date endDate = getDateParameter(...); 
Date startDate = endDate; 
startDate.setYear(endDate.getYear()-1); 

但問題是,startDateendDate不都是,其他的副本,但完全相同的對象。當您在startDate上更改日期時,您已在endDate上更改它。 您應該複製這樣的:

Date startDate = new Date(endDate.getTime()); 
+0

我不認爲這是問題,日期作爲一個字符串正常工作,因爲我已經給出,即使在同一日期之間。 –