javax.persistence.Query不设置参数

时间:2016-11-19 07:07:23

标签: java hibernate spring-data-jpa jpa-2.0 jpa-2.1

这是我正在执行的查询实例

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";

3 个答案:

答案 0 :(得分: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'

答案 1 :(得分: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'

答案 2 :(得分: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());