【问题标题】:Passing List<Integer> in spring data jpa native query在 Spring Data jpa 本机查询中传递 List<Integer>
【发布时间】:2013-11-04 15:51:33
【问题描述】:

使用spring data JPA,我正在尝试进行这种查询(它更复杂,这是一个简单的案例)

@Query(nativeQuery = true, 
       value = "SELECT * FROM events WHERE typeId IN (?1)")
List<Event> findEventsByType(List<Integer> types);

当我启动查询时,会引发异常:

org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.

我尝试过 List 、Integer[]、Object[] 和 String 但它不起作用...

我不能传递值列表吗?

进行此类查询的最佳方法是什么?

谢谢!

【问题讨论】:

  • 这是一篇很老的帖子,但你解决了吗?

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


【解决方案1】:

尝试去掉@Query 并为方法命名:

public List<Event> findByTypeIn(List<Integer> types);

见链接中的表2.2:http://docs.spring.io/spring-data/jpa/docs/1.2.0.RELEASE/reference/html/

【讨论】:

  • 我不能这样做,因为真正的查询更复杂。我在这里展示了基本情况。
  • 标题是 NativeQuery 但查询本身是一个简单的查询。答案适用于 Query,而不是 NativeQuery。不过,这对遇到上述情况的人会有所帮助。
【解决方案2】:

我尝试如下,它对我有用。

@Query(value = "select * from events where type_id in :types", nativeQuery = true)
List<Event> findEventsByType(@Param("types") List<Integer> types);

【讨论】:

    【解决方案3】:

    使用 JPQL。原生查询被或应该完全按照您创建 SQL 字符串的方式传递到数据库,除非您的驱动程序可以采用序列化集合并理解单个参数需要被解释为多个参数,否则它将无法正常工作。您传入的集合需要根据集合中元素的数量从 (?) 扩展到 (?, ?,...) 的 SQL,而 JDBC 驱动程序无法做到这一点,并且需要 JPA 提供程序按原样执行字符串。

    JPQL 查询允许 JPA 提供程序根据传入的列表动态创建所需的 SQL,因此它可以为您扩展集合。

    【讨论】:

      【解决方案4】:
      @Query(value = "SELECT c from Company c where " +
          "c.companyName IN (:company_names)")
      List<Company> findCompaniesByName(@Param("company_names") List<String> companyNames);
      

      这是您问题的解决方案。

      这里我传递了包含公司名称的列表,我正在查询数据库并将结果存储在列表中。

      希望这能帮到你!

      【讨论】:

        【解决方案5】:

        试试这个。它适用于 SpringBoot JPA 中的 Native Query:

        @Query(value = "SELECT * FROM table WHERE columnName IN (:inputList)" , 
             nativeQuery = true)
        List<Object> findByObjectList(@Param("inputList") List<Object> inputList);
        

        如果是 JPA,请尝试以下操作:

        List<Object> findByObjectList(List<Object> inputList)
        

        【讨论】:

          【解决方案6】:

          我知道这有点脱离上下文(我们使用更新而不是选择),但这对其他人可能有用:

          
              /**
               * Update the state of list of entities using their ids
               * @param ids request ids
               * @param state new state
               * @return
               */
              @Modifying
              @Query(value = "UPDATE AbstractRequest SET state = :state WHERE id IN (:ids)")
              int updateStates(@Param("ids") List<Long> ids, @Param("state") InternalRequestStep state);
          

          【讨论】:

            【解决方案7】:

            尝试这样查询:

            @Query(nativeQuery = true, 
                   value = "SELECT * FROM events WHERE typeId = ?1")
            List<Event> findEventsByType(List<Integer> types);
            

            成功了吗?

            【讨论】:

              【解决方案8】:

              在 IN 子句中以这种方式传递数组

              @Query(value = "select name from teams where name in :names", nativeQuery = true)
              List<String> getNames(@Param("names") String[] names);
              

              这样称呼

              String[] names = {"testing team","development team"};
              List<String> teamtest = teamRepository.getNames(names);
              

              【讨论】:

                【解决方案9】:

                删除 (?1) 参数周围的括号。您的查询值应如下所示:

                @Query(value = "SELECT * FROM events WHERE typeId IN ?1")
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-04-15
                  • 1970-01-01
                  • 2021-08-26
                  • 2018-12-14
                  • 2017-04-21
                  • 2021-01-11
                  • 1970-01-01
                  • 2013-11-13
                  相关资源
                  最近更新 更多