Monthly Archives: June 2010

MySQL5InnoDBDialect и поля типа TEXT

Written by elwood

Обнаружил сегодня очередной косяк в 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.