«Число столбцов не совпадает» для базы данных h2. Выберите запрос, используя проекцию в Spring-Boot @DataJpaTest - PullRequest
1 голос
/ 09 апреля 2019

У меня есть приложение 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:

1 Ответ

1 голос
/ 11 апреля 2019

Оказывается, что сообщение об ошибке на самом деле не имеет отношения к основной проблеме ничего .

База данных 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.

...