2012-03-09 3 views
4

Я использую SQL-запрос, а затем преобразовываю результат, используя Transformers.aliasToBean() Hibernates. Один из столбцов в моем запросе - это перечисление. Преобразование как-то не подходит для перечисления. Что мне делать? Какой тип данных следует использовать? Я хочу больше 1 символа, чтобы преобразовать результат в мой тип перечисления.Сбой преобразования Hibernate SQL для поля типа Enum

Это как упрощенная версия моего запроса/код выглядит следующим образом (б является перечисление в таблице профилей):

session.createSQLQuery("select a, b from profiles").setResultTransformer(Transformers.aliasToBean(Profile.class)) 
        .list(); 

Исключение: expected type: Foo.ProfileStateEnum, actual value: java.lang.Character

+0

вы хотите использовать только ** Transformers.aliasToBean ** или ** HQL ** будет делать? – ManuPK

+0

Я пишу собственный SQL-запрос, поэтому я думаю, что HQL будет недостаточно. –

ответ

10

Предполагая, что Java тип перечисления, который соответствует столбцу b, является Foo.ProfileStateEnum, следующий фрагмент кода должен работать на вас. (Я тестировал с Hibernate 4.1.6)

import java.util.Properties; 
import org.hibernate.type.Type; 
import org.hibernate.type.IntegerType; 
import org.hibernate.internal.TypeLocatorImpl.TypeLocatorImpl; 
import org.hibernate.type.TypeResolver.TypeResolver; 
import org.hibernate.type.EnumType; 

Properties params = new Properties(); 
params.put("enumClass", "Foo.ProfileStateEnum"); 
params.put("type", "12"); /*type 12 instructs to use the String representation of enum value*/ 
/*If you are using Hibernate 5.x then try: 
params.put("useNamed", true);*/ 
Type myEnumType = new TypeLocatorImpl(new TypeResolver()).custom(EnumType.class, params); 

List<Profile> profileList= getSession().createSQLQuery("select a as ID, b from profiles") 
      .addScalar("ID", IntegerType.INSTANCE) 
      .addScalar("b", myEnumType) 
      .setResultTransformer(Transformers.aliasToBean(Profile.class)) 
      .list(); 
+0

Это определенно выглядит интересно. Я это попробую. Благодарю. –

+0

Не работает в спящем режиме 5.x. Я ищу быстрое решение для hibernate 5.x. – bavon

+0

Для hibernate 5.x попробуйте params.put ("useNamed", true); вместо params.put («тип», «12»); – gunalmel

0

Давайте посмотрим, почему вы получаете это исключение.

От вопроса, очевидно, что вы использовали @Enumerated(EnumType.STRING) аннотацию для поля «б» в вас модель класса. Таким образом, поле является перечислением для вашего класса модели и varchar для вашей базы данных. Собственный SQL не интересует вас модельный класс и возвращает то, что когда-либо было в таблице базы данных, как есть. Таким образом, в вашем случае SQLQuery вы используете String для 'b' вместо ProfileStateEnum. Но ваш метод setter для 'b' в классе Profile принимает аргумент типа ProfileStateEnum.

Таким образом, вы получите исключение "ожидаемый тип: Foo.ProfileStateEnum, фактическое значение: java.lang.Character"

Вы можете использовать Aliasing, чтобы решить эту проблему.

Что я предлагаю, так же как и столбцы с любым именем, которое вы хотите, и создать метод setter для этого псевдонима в вашей модели/dto.

Например, позволяет псевдониму вашей колонке как 'enumStr'.

Тогда ваш запрос будет выглядеть следующим образом: «выберите а, б, как enumStr из профилей»

Теперь создайте метод установки для этого псевдонима в вашем Profile классе.

(Предполагая, что перечисление ProfileStateEnum может иметь любое из двух значений STATE1 и STATE2)

public void setEnumStr(String str){ 
    /*Convert the string to enum and set the field 'b'*/ 
    if(str.equals(ProfileStateEnum.STATE1.toString())){ 
     b = ProfileStateEnum.STATE1; 
    } else { 
     b = ProfileStateEnum.STATE2; 
    } 
} 

В настоящее время на преобразование, в сеттер для псевдонима setEnumStr(String) будет вызываться вместо сеттера для поля setB(ProfileStateEnum) а строка будет преобразована и сохранена в нужный вам тип без каких-либо исключений.

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

Смежные вопросы