Spring: получение ошибки грамматики неправильного sql для именованного параметра – удаление параметра устраняет ошибку

Я рассмотрел один за другим все остальные вопросы и не смог преодолеть свою проблему. Я значительно упростил код и получил, как мне кажется, новую демонстрацию проблемы. Этот код работает:

@Repository
public class MyFriend {
    @Autowired  
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    public List<TransmitUnit> getTransmissionList(LocalDate workingDate)
    {
        List<TransmitUnit> retValue = null;     
        String sql = "SELECT working_day as workingDate, origin_code as originCode FROM core.sort_transmission WHERE working_day = '2024-08-23'";
        MapSqlParameterSource namedParameters = new MapSqlParameterSource();
        namedParameters.addValue("working_day", workingDate.toString());
        retValue = namedParameterJdbcTemplate.query(sql, namedParameters, new BeanPropertyRowMapper<>(TransmitUnit.class));
        for (TransmitUnit u: retValue) {
            LOGGER.info("Got this tu {}", u.getWorkingDate());
        }
        return retValue;
    }

Если я заменю «2024-08-23» в sql именованным параметром:

String sql = "SELECT working_day as workingDate, origin_code as originCode 
FROM core.sort_transmission WHERE working_day = :working_day";

Теперь я получаю ошибку в операторе:

ERRO class = "MyFriend" method = "getTransmissionList" transactionId = "6913d8d6-d56a-4c8f-bd78-32c976817d39-1724878713995" 
request = "[2024-08-28]" errorType = "org.springframework.jdbc.BadSqlGrammarException" errorMsg = "PreparedStatementCallback; bad SQL grammar 
[SELECT working_day as workingDate, origin_code as originCode 
FROM core.sort_transmission WHERE working_day = ?]" errorOrigin = "org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104)"

Мне интересно, почему SQL показывает? как если бы это был общий подготовленный оператор, а не с именованным параметром. Я знаю, что это работало раньше, я не уверен, что я могу делать неправильно.

Обновлено: Основываясь на комментарии Джона Боллинджера, я отправил ответ, который, по моему мнению, хорошо иллюстрирует точную проблему типа и будет полезен будущим зрителям.

Главным образом потому, что это работает везде. Именованные параметры в JDBC зависят от поставщика.

talex 28.08.2024 23:14

Я не думаю, что важно, что в сообщении об ошибке параметр представлен как ?, а не с назначенным именем. Именно так драйвер преобразует его в текст для отображения.

John Bollinger 28.08.2024 23:15

@lopass, пожалуйста, также добавьте TransmitUnit в вопрос

Panagiotis Bougioukos 28.08.2024 23:21

Возможно ли, что проблема в типе данных значения параметра, которое вы вводите в ParameterSource? Если тип данных SQL рассматриваемого столбца, например, равен DATE, то может иметь значение то, что вы предоставляете строку. В том числе то, что может иметь значение, используете ли вы запрос с литералом или параметризованным запросом.

John Bollinger 28.08.2024 23:27

@JohnBollinger, возможно, проблема в этом: удаление toString() в добавлении именованного параметра приводит к тому, что код ничего не возвращает, но серьезной грамматической ошибки больше нет. Пытаюсь уговорить его что-то вернуть.

lopass 29.08.2024 01:04

JDBC имеет только позиционные параметры, и они обозначены ?. Spring выполняет за вас сопоставление именованных параметров с позиционными. Вы фокусируетесь не на том. В любом случае вам необходимо опубликовать полную трассировку стека исключений, а не просто сводку ошибок.

Mark Rotteveel 29.08.2024 11:00
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
6
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

  1. Уменьшите тип даты БД, чтобы учитывать только часть даты.

  2. Передайте localDate из Java в виде определенного строкового формата, а затем преобразуйте его в запрос SQL в дату.

    String sql = "ВЫБЕРИТЕ рабочий_день как рабочую дату, исходный_код как исходный код FROM core.sort_transmission WHERE trunc(working_day) = ':working_day'";

    MapSqlParameterSource NameParameters = новый MapSqlParameterSource ();

    названныйParameters.addValue("рабочий_день",workDate.format(DateTimeFormatter.ofPattern("дд-ММ-гггг"));

Ответ принят как подходящий

Джон Боллинджер был прав. Тип в Java должен соответствовать типу в SQL. Удаление toString() сработало.

Окончательный рабочий код:

@Repository
public class MyFriend {
    @Autowired  
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    public List<TransmitUnit> getTransmissionList(LocalDate workingDate)
    {
        List<TransmitUnit> retValue = null;     
        String sql = "SELECT working_day as workingDate, origin_code as originCode FROM core.sort_transmission WHERE working_day = :working_day";
        MapSqlParameterSource namedParameters = new MapSqlParameterSource();
        namedParameters.addValue("working_day", workingDate);
        retValue = namedParameterJdbcTemplate.query(sql, namedParameters, new BeanPropertyRowMapper<>(TransmitUnit.class));
        for (TransmitUnit u: retValue) {
            LOGGER.info("Got this tu {}", u.getWorkingDate());
        }
        return retValue;
    }

Другие вопросы по теме

Ошибка создания bean-компонента с именем «entityManagerFactory», определенным в ресурсе пути к классу: невозможно построить Hibernate SessionFactory;
Как использовать внешние файлы конфигурации для обеспечения специфичных для среды конфигураций в приложении Spring Boot?
@SpringBootTest Тесты с WebTestClient не работают после перехода с Spring-boot-starter-parent версии 3.2.5 на 3.3.3
CVE-2024-38809: DoS Spring Framework через условный HTTP-запрос
Как динамически обрабатывать предложение WHERE, если от клиента не было отправлено никаких входных параметров
Невозможно внедрить @Repository в @Service
Клиент Spring OAuth2 выполняет выход из обратного канала с истекшим идентификатором токена
Фильтрация представления таблицы
Дублирующая ошибка определения макета при использовании @MockBean для переопределения bean-компонента в нескольких тестовых классах Spring Boot
Как исправить java.lang.NoClassDefFoundError для javax/xml/bind/DatatypeConverter