【问题标题】:"Column count does not match" for h2 database Select query using projection in Spring-Boot @DataJpaTesth2数据库的“列数不匹配”使用Spring-Boot @DataJpaTest中的投影选择查询
【发布时间】:2019-08-31 03:36:17
【问题描述】:

我有一个 Spring-Boot 应用程序,它有一些使用内容投影的本机查询。它在生产中运行 Postgres 并且工作正常。我正在尝试使用@DataJpaTest 和 h2 内存数据库为存储库设置集成测试,但我使用内容投影的查询失败,驱动程序出现 JdbcSQLException:

org.h2.jdbc.JdbcSQLException:列数不匹配

我成功保存到TestEntityManager,所以数据库中有记录,但是我无法通过repository方法调用SELECT。 它在 Postgres 上的生产环境中正常工作——这是对 h2 的限制吗?有没有我可以应用的解决方法,以便我可以正确测试它?

存储库方法如下所示(一个内连接,where 子句中的两个参数,表名和列更改以保护有罪):

public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {

    @Query(nativeQuery = true,
           value = "SELECT order.id, order.total, pizza.name " +
                   "FROM example.order " +
                   "INNER JOIN example.pizza USING (pizza_id) " +
                   "WHERE order.customer_id = :custId " +
                   "AND order.order_date = :orderDate ",
           countQuery = "SELECT count(order.id) " +
                        "FROM example.order " +
                        "INNER JOIN example.pizza USING (pizza_id) " +
                        "WHERE order.customer_id = :custId " +
                        "AND order.order_date = :orderDate")
    <T> Page<T> findAllByCustIdAndOrderDate(String custId, OffsetDateTime orderDate, Pageable paging, Class<T> type);
}

投影看起来像这样:

public interface PizzaOrderProjection {
  Long getId();
  Double getTotal();
  String getName();
}

当我调用findAllByCustIdAndOrderDate 时触发异常,它打印的 SQL 语句导致它是 SELECT。它打印的 SELECT 看起来非常正常:

Hibernate: 
    /* dynamic native SQL query */ SELECT
        order.id,
        order.total,
        pizza.name 
    FROM
        example.order 
    INNER JOIN
        example.pizza USING (pizza_id) 
    WHERE
        order.customer_id = ? 
        AND order.order_date = ?  limit ?
2019-04-09 12:42:18.704  WARN 17568 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 21002, SQLState: 21S02
2019-04-09 12:42:18.708 ERROR 17568 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column count does not match; SQL statement:

【问题讨论】:

    标签: spring-data-jpa h2


    【解决方案1】:

    事实证明,错误消息实际上与根本问题无关

    H2 数据库不支持inner join 子句上的using 关键字,只支持on 关键字。

    通过将内部连接更改为使用 on 来解决问题,如下所示:

    public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
    
        @Query(nativeQuery = true,
               value = "SELECT order.id, order.total, pizza.name " +
                       "FROM example.order " +
                       "INNER JOIN example.pizza ON order.pizza_id = pizza.pizza_id " +
                       "WHERE order.customer_id = :custId " +
                       "AND order.order_date = :orderDate ",
               countQuery = "SELECT count(order.id) " +
                            "FROM example.order " +
                            "INNER JOIN example.pizza ON order.pizza_id = pizza.pizza_id " +
                            "WHERE order.customer_id = :custId " +
                            "AND order.order_date = :orderDate")
        <T> Page<T> findAllByCustIdAndOrderDate(String custId, OffsetDateTime orderDate, Pageable paging, Class<T> type);
    }
    

    此更改使查询在 postgres 和 h2 中均有效。

    【讨论】:

    • 与 SQL Server 关键字 (nolock) 有同样的问题。查询是:@Query(nativeQuery = true, value = "SELECT count(d.id) FROM doc_log d (NOLOCK) " + "WHERE d.doc_value = ?1 AND d.status in (?2)") int countByDocValueAndStatusIn(String docValue, List&lt;Long&gt; statuses); 删除后 (nolock) 一切正常。
    猜你喜欢
    • 2016-05-15
    • 2019-09-06
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    相关资源
    最近更新 更多