Как я могу предотвратить Hibernate от обрезки строк? - PullRequest
3 голосов
/ 06 марта 2009

Я использую Oracle 10g и Hibernate 2.1 (старая версия, но не разрешено обновлять, чтобы исправить). У меня есть таблица с необнуляемым столбцом с именем TIN, varchar2 (9). Этот столбец используется для размещения данных, загружаемых из плоских файлов, и поэтому может хранить любую строку длиной 9, включая 9 пробелов (то есть: ''), если входной файл имеет 9 пробелов.

Что я заметил, так это:

  1. Oracle 10g автоматически преобразует пустые строки в NULL. Так что если вы выполните:

    SELECT NVL('', 'Input string converted to NULL') FROM dual; 
    

    Результатом является 'Входная строка, преобразованная в NULL', а не ''. Я думаю, что это имеет отношение к проблеме.

  2. Когда Hibernate считывает запись, в которой значение TIN составляет 9 пробелов (или любое количество пробелов) без других символов, оно сохраняет значение в памяти как ''. Затем, похоже, Hibernate заставляет себя задуматься, так что значение изменилось с 9 пробелов на пустую строку. Затем, если запись записывается обратно в базу данных, Hibernate пытается записать пустую строку, а не 9 пробелов, и Oracle, очевидно, преобразует ее в ноль, а затем выбрасывает ненулевое ограничение ограничения.

Для справки, вот HBM для этого столбца:

<property
    name="tin"
    type="java.lang.String"
    column="TIN"
    not-null="true"
    length="9">

У меня вопрос: как я могу указать Hibernate не преобразовывать значения, содержащие только пробелы, в пустые строки?

Обновление 1: я только что вернулся и протестировал строки типа 'text' и обнаружил, что Hibernate также обрезает эти пробелы, делая строку 'text' и обманывая себя, думая, что значение изменилось. Я должен что-то упустить. Это не похоже на поведение по умолчанию.

Обновление 2. Похоже, что задача Ant hbm2java, которая преобразует HBM в исходный код Java, может быть источником обрезки строки. Все еще расследую.

Спасибо, Джефф

Редактировать: изменена формулировка вопроса, чтобы быть более точной.

Ответы [ 3 ]

4 голосов
/ 06 марта 2009

Один из способов справиться с этим - создать Hibernate UserType . В ссылке на hibernate.org есть инструкции с некоторыми уже сделанными классами для выхода из строки. Я понимаю, что это не дает прямого ответа «как сказать hibernate не преобразовывать 9 пробелов в пустую строку», но это решит проблему хранения на стороне базы данных.

На этой странице есть 2 реализации - одна, которая экранирует все строки (может обрабатывать ваш случай 9 пробелов по вашему желанию), и та, которая только экранирует значение ''. Похоже, что первый может быть лучше для вас.

Для справки - я сам использую этот метод. Все, что вам нужно сделать, это иметь класс в вашем classpath и установить для атрибута 'type' в вашем HBM.xml полное имя класса (т.е. добавьте type = "my.fully.qualified.HibernateUserType" в свой элемент свойства).

На стороне Java ваши классы будут по-прежнему иметь дело непосредственно с java.lang.String и значениями, которые вы ожидаете увидеть, но в спящем режиме они будут использовать класс UserType.

3 голосов
/ 07 марта 2009

Оказалось, что проблема не в Hibernate. Проект, над которым я работаю, был настроен на создание Java POJO из файлов HBM с помощью задачи Ant hbm2java. Это, в свою очередь, ссылается на исходный шаблон для getters / setters / equals / toString / etc, который был написан для обрезки всех свойств java.lang.String в сеттере. Чтобы устранить проблему, я пассивировал один класс, с которым у меня были проблемы, чтобы он больше не генерировался при каждой сборке, а затем удалил усечение в свойстве TIN.

2 голосов
/ 06 марта 2009

Я не знаю о спящем. Но я знаю, что Oracle обрабатывает пустые строки как нулевые значения. И нет никакого обходного пути для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...