Monthly Archives: June 2010
Обнаружил сегодня очередной косяк в Hibernate, когда делал NativeQuery для таблицы, в
которой имеется поле типа TEXT. Как известно, хибер по умолчанию не создает такие поля,
а создает VARCHAR(255) для строковых значений, и
тип TEXT я задал специально при создании Entity-бинов с использованием аннотации
@Column(columnDefinition = “text”). И вот теперь select через NativeQuery не работает,
потому что
MySQL5: No Dialect mapping for JDBC type: -1
Из обсуждений http://opensource.atlassian.com/projects/hibernate/browse/HHH-1483
выяснилось, что этот диалект почему-то не хочет поддерживать тип TEXT.
В результате выяснилось, что победить эту проблему можно тремя способами :
1. Отказаться от использования TEXT в пользу VARCHAR(65535) – но это не всегда возможно,
особенно если база уже работает, и при выполнении alter table часть данных будет обрезана.
2. Заюзать хибернейтовский метод addScalar при формировании запроса.
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html (16.1.1 Scalar queries)
К сожалению, этот метод также не является идеальным, поскольку при использовании
EJB3 (а я использую именно его) не представляется возможным лезть на уровень ниже и
кастить интерфейс Query к хибернейтовскому SQLQuery, тем самым завязываясь на текущей
хибернейтовской имплементации EJB3.
3. Пропатчить класс-диалект, подменив его своим или занаследовавшись от него и добавив
специальный кейс для типа TEXT. В данном случае все прошло великолепно, я закинул
класс
public class MySQL5InnoDBDialectPatched extends org.hibernate.dialect.MySQL5InnoDBDialect { public MySQL5InnoDBDialectPatched() { super(); // register additional hibernate types for default use in scalar sqlquery type auto detection registerHibernateType(Types.LONGVARCHAR, org.hibernate.Hibernate.TEXT.getName()); } } |
в свойства persistence.xml, и все заработало.
Единственное, что пришлось добавить в проект – compile-time-зависимости для сборки
ejb-джарника. В моем случае это был всего лишь 1 файл hibernate3.jar.
2