Один и тот же код Java не работает для всех JDK

У меня есть код:

@PersistenceContext
private EntityManager em;

public void call() {


    String input = "<ROOT>" +
                       "<START_DATE>20240824</START_DATE>" +
                    "</ROOT>";

    StoredProcedureQuery proc = em.createStoredProcedureQuery("procedureName");
    proc.registerStoredProcedureParameter("inXml", String.class, ParameterMode.IN);
    proc.registerStoredProcedureParameter("outXml", String.class, ParameterMode.OUT);
    proc.registerStoredProcedureParameter("error", String.class, ParameterMode.OUT);

    proc.setParameter("inXml", input);

    proc.execute();

    var outXml = (String) proc.getOutputParameterValue("outXml");
    var error = (String) proc.getOutputParameterValue("error");

    log.info(outXml);
    log.info(error);

}

Это приложение Spring Boot (версия 3.0.7). Я вызываю хранимую процедуру в базе данных Oracle с датой в качестве параметра. Я запускаю код на двух компьютерах:

1. Java установлена ​​= openjdk version "17.0.9" 2023-10-17 OpenJDK Runtime Environment Temurin-17.0.9+9 (build 17.0.9+9) OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode, sharing)

2. Java установлена ​​= openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment (build 17.0.2+8-86) OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

Номер 1 работает нормально, но номер 2 выдает ошибку = ORA-01861: literal does not match format string

Не могли бы вы сказать мне, почему тот же код не работает на сервере номер 2?

🤔 А знаете ли вы, что...
Oracle Database 19c - это последняя версия базы данных Oracle на момент завершения моего обучения в сентябре 2021 года.


81
1

Ответ:

Решено

Программы подключаются к одному и тому же серверу, но каждое из двух подключений запускает разные сеансы, и эти сеансы (по какой-то причине) имеют разные параметры сеанса NLS.

Где-то в вашей процедуре вы выполняете неявное преобразование строки в DATE:

  • В первом сеансе NLS_DATE_FORMAT соответствует YYYYMMDD, и неявное преобразование завершается успешно.
  • Во втором сеансе NLS_DATE_FORMAT не соответствует YYYYMMDD, и неявное преобразование завершается с ошибкой ORA-01861: literal does not match format string.

Решение состоит в том, чтобы НИКОГДА не полагаться на неявные преобразования.

Вы не предоставляете исходный код своей процедуры, но если вы используете TO_DATE(value), измените его, чтобы использовать модель явного формата TO_DATE(value, 'YYYYMMDD'). Аналогично, если вы полагаетесь на неявные преобразования в функциях XML, не полагайтесь на неявное преобразование; сделайте это явным.


Альтернативное решение — создать триггер входа в систему, чтобы в начале каждого запускаемого вами сеанса:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDD';

Чтобы установить модель формата, которую Oracle использует для неявных преобразований строк в дату (и наоборот). Однако это не лучшая практика, и вам следует исправить свой код, чтобы он не полагался на неявные преобразования.