Я рассмотрел один за другим все остальные вопросы и не смог преодолеть свою проблему. Я значительно упростил код и получил, как мне кажется, новую демонстрацию проблемы. Этот код работает:
@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 показывает? как если бы это был общий подготовленный оператор, а не с именованным параметром. Я знаю, что это работало раньше, я не уверен, что я могу делать неправильно.
Обновлено: Основываясь на комментарии Джона Боллинджера, я отправил ответ, который, по моему мнению, хорошо иллюстрирует точную проблему типа и будет полезен будущим зрителям.
Я не думаю, что важно, что в сообщении об ошибке параметр представлен как ?
, а не с назначенным именем. Именно так драйвер преобразует его в текст для отображения.
@lopass, пожалуйста, также добавьте TransmitUnit
в вопрос
Возможно ли, что проблема в типе данных значения параметра, которое вы вводите в ParameterSource
? Если тип данных SQL рассматриваемого столбца, например, равен DATE
, то может иметь значение то, что вы предоставляете строку. В том числе то, что может иметь значение, используете ли вы запрос с литералом или параметризованным запросом.
@JohnBollinger, возможно, проблема в этом: удаление toString() в добавлении именованного параметра приводит к тому, что код ничего не возвращает, но серьезной грамматической ошибки больше нет. Пытаюсь уговорить его что-то вернуть.
JDBC имеет только позиционные параметры, и они обозначены ?
. Spring выполняет за вас сопоставление именованных параметров с позиционными. Вы фокусируетесь не на том. В любом случае вам необходимо опубликовать полную трассировку стека исключений, а не просто сводку ошибок.
Уменьшите тип даты БД, чтобы учитывать только часть даты.
Передайте 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;
}
Главным образом потому, что это работает везде. Именованные параметры в JDBC зависят от поставщика.