Спящий режим и заполнение столбца первичного ключа CHAR в Oracle - PullRequest
3 голосов
/ 15 декабря 2009

У меня небольшие проблемы с использованием Hibernate со столбцом char (6) в Oracle. Вот структура таблицы:

CREATE TABLE ACCEPTANCE
(
   USER_ID char(6) PRIMARY KEY NOT NULL,
   ACCEPT_DATE date
);

Для записей, чей идентификатор пользователя содержит менее 6 символов, я могу выбрать их без добавления идентификатора пользователя при выполнении запросов с использованием SQuirreL. И.Е. следующее возвращает запись, если есть запись с идентификатором пользователя «abc».

select * from acceptance where user_id = "abc"

К сожалению, при выполнении выбора через Hibernate (JPA) следующее возвращает ноль:

em.find(Acceptance.class, "abc");

Если я добавлю значение, он вернет правильную запись:

em.find(Acceptance.class, "abc   ");

Модуль, над которым я работаю, получает идентификатор пользователя, незаполненный из других частей системы. Есть ли лучший способ заставить Hibernate работать иначе, чем вставлять код для адаптации идентификатора пользователя к определенной длине перед передачей его в Hibernate? (что может привести к проблемам с техническим обслуживанием в будущем, если длина изменится)

Ответы [ 2 ]

3 голосов
/ 15 декабря 2009

Это Божий способ сказать вам никогда не использовать CHAR () для первичного ключа: -)

Серьезно, однако, поскольку ваш user_id отображается как строка в вашей сущности, диалект Oracle в Hibernate переводит это в varchar. Поскольку Hibernate использует подготовленные операторы для всех своих запросов, эта семантика переносится (в отличие от SQuirreL, где значение указывается как литерал и, следовательно, преобразуется по-разному).

На основе Oracle правил преобразования типов значение столбца затем повышается до varchar2 и сравнивается как таковое; Таким образом, вы не получите никаких записей.

Если вы не можете изменить базовый тип столбца, лучше всего использовать HQL-запрос и функцию rtrim(), поддерживаемую Oracle на диалекте.

1 голос
/ 15 декабря 2009

Как получилось, что ваш модуль получает незаполненное значение из других частей системы?

Согласно моему пониманию, если другая часть системы не изменяет PK, они должны прочитать 6 символов из БД и пропустить 6 символов по пути - это было бы хорошо. Единственное исключение будет при создании PK, и в этом случае его может потребоваться заполнить.

Вы можете обойти проблему (обрезая или дополняя значение каждый раз, когда это необходимо), но это не решит проблему заранее, поскольку ваш PK не обрабатывается согласованно. Чтобы решить проблему заранее, вы должны eiher

  • всегда получает 6 символов из других частей модуля
  • используйте varchar2 для правильной обработки динамического размера

Если вы не можете решить проблему заранее, тогда вам действительно потребуется либо

  • добавить обрезку / заполнение по всему месту при необходимости
  • добавить обрезку / заполнение в DAO, если у вас есть
  • добавить обрезку / заполнение в типе пользователя, если это работает (предложение Н. Хьюза)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...