jpa命名本机查询无结果

Posted

技术标签:

【中文标题】jpa命名本机查询无结果【英文标题】:Jpa named native query no result 【发布时间】:2020-02-24 21:16:33 【问题描述】:

我正在尝试将 java spring 云微服务连接到 oracle 数据库。 我的问题是,当我调用从函数传递参数的本机查询时,这不会向我返回任何内容,而如果我将其参数直接插入查询中,一切正常。

实体

@Entity
@Table(name = "######")
@SqlResultSetMapping(
        name    = "EmployeeJobDTO",
        classes = @ConstructorResult(
                targetClass = EmployeeJobDTO.class,
                columns     = 
                        @ColumnResult(name = "idStf",           type = String.class),
                        @ColumnResult(name = "personalNumber",  type = String.class),
                        @ColumnResult(name = "name",            type = String.class),
                        @ColumnResult(name = "surname",         type = String.class),
                        @ColumnResult(name = "functionMain",    type = String.class),
                        @ColumnResult(name = "idDrr",           type = String.class),
                        @ColumnResult(name = "functionShift",   type = String.class),
                        @ColumnResult(name = "shiftOldCode",    type = String.class),
                        @ColumnResult(name = "shiftCode",       type = String.class),
                        @ColumnResult(name = "idJob",           type = String.class),
                        @ColumnResult(name = "jobType",         type = String.class),
                        @ColumnResult(name = "jobStatus",       type = String.class),
                        @ColumnResult(name = "plannedFrom",     type = String.class),
                        @ColumnResult(name = "plannedTo",       type = String.class),
                        @ColumnResult(name = "actualFrom",      type = String.class),
                        @ColumnResult(name = "actualTo",        type = String.class)
                ) 
        )
@NamedNativeQueries(
    @NamedNativeQuery(
            name                = "findDayJobsByDateAndDepartment",
            resultClass         = EmployeeJobDTO.class,
            resultSetMapping    = "EmployeeJobDTO",
            query   = "select to_char(st.XXXX) as idStf," + 
                    "st.XXXX as personalNumber," + 
                    "st.XXXX as name," + 
                    "st.XXXX as surname," + 
                    "sp.XXXX as functionMain," + 
                    "dr.XXXX as idDrr," + 
                    "dr.XXXX as functionShift," + 
                    "dr.XXXX as shiftOldCode," + 
                    "dr.XXXX as shiftCode," + 
                    "jb.XXXX as idJob," + 
                    "jb.XXXX as jobType," + 
                    "substr(jb.XXXX, 0, 1) as jobStatus," + 
                    "jb.XXXX as plannedFrom," + 
                    "jb.XXXX as plannedTo," + 
                    "jb.XXXX as actualFrom," + 
                    "jb.XXXX as actualTo " + 
                    "from XXXXXX jb " + 
                    "inner join XXXXXX dr on jb.XXXX = dr.XXXX " + 
                    "inner join XXXXXX st on jb.XXXX = st.XXXX " + 
                    "inner join XXXXXX sr on sr.XXXX = jb.XXXX " + 
                    "inner join XXXXXX sp on sp.XXXX = jb.XXXX " +
                    "where dr.XXXX=?1 and dr.XXXX = 'A' and sr.XXXX=?2"
            ),
    @NamedNativeQuery(
            name                = "findDayJobsByDateAndDepartmentFixedParam",
            resultClass         = EmployeeJobDTO.class,
            resultSetMapping    = "EmployeeJobDTO",
            query   = "select to_char(st.XXXX) as idStf," + 
                    "st.XXXX as personalNumber," + 
                    "st.XXXX as name," + 
                    "st.XXXX as surname," + 
                    "sp.XXXX as functionMain," + 
                    "dr.XXXX as idDrr," + 
                    "dr.XXXX as functionShift," + 
                    "dr.XXXX as shiftOldCode," + 
                    "dr.XXXX as shiftCode," + 
                    "jb.XXXX as idJob," + 
                    "jb.XXXX as jobType," + 
                    "substr(jb.XXXX, 0, 1) as jobStatus," + 
                    "jb.XXXX as plannedFrom," + 
                    "jb.XXXX as plannedTo," + 
                    "jb.XXXX as actualFrom," + 
                    "jb.XXXX as actualTo " + 
                    "from XXXXXX jb " + 
                    "inner join XXXXXX dr on jb.XXXX = dr.XXXX " + 
                    "inner join XXXXXX st on jb.XXXX = st.XXXX " + 
                    "inner join XXXXXX sr on sr.XXXX = jb.XXXX " + 
                    "inner join XXXXXX sp on sp.XXXX = jb.XXXX " +
                    "where dr.XXXX='20200224' and dr.XXXX = 'A' and sr.XXXX='SFA'"
            )
)
public class EmployeeJobEntity 
    //.............. follows the code .....

存储库

public interface EmployeeJobEntityRepository extends CrudRepository<EmployeeJobEntity, String> 
    // This query return [] i tryed @Param annotation and the result not change.
    @Query(name = "findDayJobsByDateAndDepartment", nativeQuery = true)
    public List<EmployeeJobDTO> findDayJobsByDateAndDepartment(String date, String department);

    // This query return the data OK
    @Query(name = "findDayJobsByDateAndDepartmentFixedParam", nativeQuery = true)
    public List<EmployeeJobDTO> findDayJobsByDateAndDepartmentFixedParam();

APPLICATION.YML

logging:
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          descriptor:
            sql:
              BasicBinder: TRACE
server:
  port: 8100
spring:
  application:
    name: employee
  datasource:
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@XXXX-XXX.XX.it:<port>:<sid>
    password: XXXX
    username: XXXX
    hikari:
      connection-test-query: select 1 from dual
      minimum-idle: 1
      idle-timeout: 240000
      max-lifetime: 360000
      maximum-pool-size: 10
      pool-name: XXXX
  jpa:
    hibernate:
      ddl-auto: none
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.Oracle10gDialect

POM.XML 依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.3</version>
</dependency>

日志控制台

[springProfile_IS_UNDEFINED] - [DEBUG] 2020-02-25 08:47:20 [http-nio-8100-exec-2] o.h.SQL - [employee,] 
    select
        to_char(st.XXXX) as idStf,
        st.XXXX as personalNumber,
        st.XXXX as name,
        st.XXXX as surname,
        sp.XXXX as functionMain,
        dr.XXXX as idDrr,
        dr.XXXX as functionShift,
        dr.XXXX as shiftOldCode,
        dr.XXXX as shiftCode,
        jb.XXXX as idJob,
        jb.XXXX as jobType,
        substr(jb.XXXX,
        0,
        1) as jobStatus,
        jb.XXXX as plannedFrom,
        jb.XXXX as plannedTo,
        jb.XXXX as actualFrom,
        jb.XXXX as actualTo 
    from
        XXXXXX jb 
    inner join
        XXXXXX dr 
            on jb.XXXX = dr.XXXX 
    inner join
        XXXXXX st 
            on jb.XXXX = st.XXXX 
    inner join
        XXXXXX sr 
            on sr.XXXX = jb.XXXX 
    inner join
        XXXXXX sp 
            on sp.XXXX = jb.XXXX 
    where
        dr.XXXX =? 
        and dr.XXXX = 'A' 
        and sr.XXXX =?
[springProfile_IS_UNDEFINED] - [TRACE] 2020-02-25 08:47:20 [http-nio-8100-exec-2] o.h.t.d.s.BasicBinder - [employee,] binding parameter [1] as [VARCHAR] - [20200224]
[springProfile_IS_UNDEFINED] - [TRACE] 2020-02-25 08:47:20 [http-nio-8100-exec-2] o.h.t.d.s.BasicBinder - [employee,] binding parameter [2] as [VARCHAR] - [SFA]

【问题讨论】:

【参考方案1】:

您需要使用 spring 的注释 @Param,对于您的情况,代码如下所示:

@Query(name = "findDayJobsByDateAndDepartment", nativeQuery = true)
    public List<EmployeeJobDTO> findDayJobsByDateAndDepartment(@Param("date") String date, @Param("department") String department);

link 中有关 Spring JPA 的更多参考

【讨论】:

感谢您的回答,我已经尝试使用@Param 注释,但结果没有改变。【参考方案2】:

我通过修改查询解决了,department字段是一个char[8]。

    query   = "select to_char(st.XXXX) as idStf," + 
            "st.XXXX as personalNumber," + 
            "st.XXXX as name," + 
            "st.XXXX as surname," + 
            "sp.XXXX as functionMain," + 
            "dr.XXXX as idDrr," + 
            "dr.XXXX as functionShift," + 
            "dr.XXXX as shiftOldCode," + 
            "dr.XXXX as shiftCode," + 
            "jb.XXXX as idJob," + 
            "jb.XXXX as jobType," + 
            "substr(jb.XXXX, 0, 1) as jobStatus," + 
            "jb.XXXX as plannedFrom," + 
            "jb.XXXX as plannedTo," + 
            "jb.XXXX as actualFrom," + 
            "jb.XXXX as actualTo " + 
            "from XXXXXX jb " + 
            "inner join XXXXXX dr on jb.XXXX = dr.XXXX " + 
            "inner join XXXXXX st on jb.XXXX = st.XXXX " + 
            "inner join XXXXXX sr on sr.XXXX = jb.XXXX " + 
            "inner join XXXXXX sp on sp.XXXX = jb.XXXX " +
            "where dr.XXXX=:date and dr.XXXX = 'A' and trim(sr.XXXX) = :department"

我不明白为什么通过雕刻查询中的字段没有发生错误!

【讨论】:

以上是关于jpa命名本机查询无结果的主要内容,如果未能解决你的问题,请参考以下文章

JPA 本机查询结果集映射到具有子类的实体类

有没有办法获取带有结果集的 JPA 命名查询的计数大小?

使用 JPA 2.1,我如何将本机查询结果映射到 @Transient 字段(taht is a Set)?

JPA 中的传递列表命名本机查询

如何使用 JpaRepository 从 xml 中的命名本机查询返回 Map 作为结果

JPA将列表传递给命名本机查询中的IN子句