Hibernate / JPA不检测位置参数

时间:2017-06-28 11:53:08

标签: java sql hibernate jpa

我正在使用Native Query,但Hibernate / JPA不起作用,它总是抛出

  

javax.ejb.EJBTransactionRolledbackException:带有该参数   位置1不存在

原始SQL脚本:(在SQL编辑器中可以正常工作)

SELECT CAST(filteredValue.measured_at AS DATE) AS DATE,date_part('hour', filteredValue.measured_at) AS HOUR, filteredValue.source_id, AVG( filteredValue.value ) AS avg_concentration, filteredValue.code
FROM ( SELECT * FROM pollutant_value
         WHERE measured_at >= '2017-06-27 11:00:00' AND measured_at <= '2017-06-28 11:00:00'
    ) filteredValue
GROUP BY filteredValue.source_id, filteredValue.code, CAST(filteredValue.measured_at AS DATE),date_part('hour', filteredValue.measured_at)
ORDER BY CAST(filteredValue.measured_at AS DATE) DESC, date_part('hour', filteredValue.measured_at) DESC, filteredValue.source_id ASC, filteredValue.code ASC

Java实体类

@Entity
@Table(name = "pollutant_value")
@NamedQueries({
    @NamedQuery(name = PollutantValueEntity.FIND_ALL_BY_SOURCE_ID, query = "SELECT p FROM PollutantValueEntity p WHERE p.sourceId = :sourceId"),
    @NamedQuery(name = PollutantValueEntity.COUNT_BY_CODE, query = "SELECT COUNT(p.id) FROM PollutantValueEntity p WHERE p.code = :code"),
    @NamedQuery(name = PollutantValueEntity.FIND_ALL, query = "SELECT p FROM PollutantValueEntity p")})

@NamedNativeQueries({
    @NamedNativeQuery(name = PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY, query = "SELECT CAST(filteredValue.measured_at AS date) AS date, date_part('hour', filteredValue.measured_at) AS hour, filteredValue.source_id, AVG(filteredValue.value) AS avg_concentration, filteredValue.code "
        + "FROM (SELECT * FROM pollutant_value" + "WHERE measured_at >= ?1 AND measured_at <= ?2) filteredValue"
        + "GROUP BY filteredValue.source_id, filteredValue.code, CAST (filteredValue.measured_at AS date), date_part('hour', filteredValue.measured_at)"
        + "ORDER BY CAST(filteredValue.measured_at AS date) DESC, date_part('hour', filteredValue.measured_at) DESC, filteredValue.source_id ASC, filteredValue.code ASC ", resultSetMapping = PollutantValueEntity.AVG_POLLUTANT_VALUE_RESULT_MAPPER) })
@SqlResultSetMapping(name = PollutantValueEntity.AVG_POLLUTANT_VALUE_RESULT_MAPPER, classes = {
    @ConstructorResult(targetClass = AvgGroupedPollutantValueByHourEntity.class, columns = {
        @ColumnResult(name = "date"), @ColumnResult(name = "hour"), @ColumnResult(name = "source_id"),
        @ColumnResult(name = "avgConcentration"), @ColumnResult(name = "code") }) })
public class PollutantValueEntity extends GenericEntity implements Serializable {

    private static final String PREFIX = "com.axonactive.iot.sniffer.entity.PollutantValueEntity";

    public static final String FIND_ALL_BY_SOURCE_ID = PREFIX + ".findBySniffer";

    public static final String FIND_ALL = PREFIX + ".findAll";

    public static final String COUNT_BY_CODE = PREFIX + ".countByCode";

    public static final String FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY = PREFIX + ".findAvgConcentrationByHourInDay";

    public static final String AVG_POLLUTANT_VALUE_RESULT_MAPPER = PREFIX + ".averagePollutantResult";

服务电话

 public List<AvgGroupedPollutantValueByHourEntity> getAvgPollutantValuesByLowerBoundAndUpperBound( Date lowerBound, Date upperBound){
    Query query = getEm().createNativeQuery(PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY, PollutantValueEntity.AVG_POLLUTANT_VALUE_RESULT_MAPPER);
    query.setParameter(1, "2017-06-27 11:00:00");
    query.setParameter(2, "2017-06-28 11:00:00");
    return query.getResultList();
    }

我不知道为什么NamedNativeQuery PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY没有按预期采用参数。

我错过了什么吗?

编辑#1:

因为EntityManager的createNativeQuery方法接受SQL查询字符串,但在实体类中,我用名称声明它。 那么我怎么能用注释

保留这个命名的本机查询的名称
  

@NamedNativeQuery

并从EntityManager em创建,因为em没有像createNamedNativeQuery这样的方法 enter image description here

2 个答案:

答案 0 :(得分:1)

您的问题是您定义了一个NAMED查询,然后像这样调用它

Query query = em.createNativeQuery(PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY, PollutantValueEntity.AVG_POLLUTANT_VALUE_RESULT_MAPPER);
query.setParameter(1, "2017-06-27 11:00:00");
query.setParameter(2, "2017-06-28 11:00:00");
return query.getResultList();

基本上用SQL创建一个查询,无论String是什么&#34; PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY&#34; 即&#34; com.axonactive.iot.sniffer.entity.PollutantValueEntity.findAvgConcentrationByHourInDay &#34;这不是SQL清楚。如果使用该方法,则直接将SQL传递给createNativeQuery方法。

NAMED查询应该像这样实例化

query = em.createNamedQuery(PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY);
query.setParameter(1, "2017-06-27 11:00:00");
query.setParameter(2, "2017-06-28 11:00:00");
return query.getResultList();

然后你应该可以在它上面设置你的参数,因为那里有要调用的实际SQL

答案 1 :(得分:0)

请勿在之后使用数字。写,而不是?1

@NamedNativeQuery(name = PollutantValueEntity.FIND_AVG_CONCENTRATION_BY_HOUR_IN_DAY, query = "SELECT CAST(filteredValue.measured_at AS date) AS date, date_part('hour', filteredValue.measured_at) AS hour, filteredValue.source_id, AVG(filteredValue.value) AS avg_concentration, filteredValue.code "
    + "FROM (SELECT * FROM pollutant_value" + "WHERE measured_at >= ? AND measured_at <= ?) filteredValue"
    + "GROUP BY filteredValue.source_id, filteredValue.code, CAST (filteredValue.measured_at AS date), date_part('hour', filteredValue.measured_at)"
    + "ORDER 

查看Hibernate文档:https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html

  

16.1.7。参数

     

本机SQL查询支持位置和命名参数:

Query query = sess.createSQLQuery("SELECT * FROM CATS WHERE NAME like ?").addEntity(Cat.class);
List pusList = query.setString(0, "Pus%").list();