h2数据库的“列数不匹配”在Spring-Boot @DataJpaTest中使用投影选择查询

问题描述 投票:0回答:1

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

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

我成功保存到TestEntityManager,因此数据库中有记录,但我无法通过存储库方法调用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个回答
1
投票

事实证明,错误消息实际上与底层问题无关。

H2数据库不支持using子句中的inner join关键字,仅支持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中都有效。

© www.soinside.com 2019 - 2024. All rights reserved.