Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

JPA, Hibernate, persistence, FetchType

32K
20 октября 2010 года
LLIbIcpEP
32 / / 06.07.2008
Доброго времени суток. Есть такое дело:
 
Код:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Unit {
   
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @NotNull(message = "id is required")
    @Column(nullable = false, unique=true)
    private Long id;

 
Код:
@Entity
public class MessageDependency extends Unit {
   
    @ManyToOne(fetch=FetchType.LAZY)
    @NotNull(message = "Owner is required")
    private UserInstance owner;
   
    @ManyToOne(fetch=FetchType.LAZY)
    @NotNull(message = "Dependency is required")
    private Unit dependency;

 
Код:
@Entity
public class UserInstance extends Unit {
   
    @NotNull(message = "uid is required")
    @Column(nullable = false, unique=true)
    @Min(1)
    private Long uid;

Древо наследования достаточно большое, UserInstance - прямой наследник Unit, поле dependency может содержать все что угодно, унаследованное от Unit. Делаю примерно так:
 
Код:
UserInstance userInstance = entityManager.createQuery(
    "select u from UserInstance u where u.uid = :p0", UserInstance.class)
        .setParameter("p0", 1l).getSingleResult();
mess = entityManager.createQuery(
    "select m from MessageDependency m fetch all properties where m.owner = :p0",
        MessageDependency.class).setParameter("p0", userInstance).getResultList();

Потом сериализую полученный лист в JSON через XStream. Вообщем в итоге у меня поле dependency сериализуется как прокси, не смотря на "fetch all properties" в HQL. Почему "fetch all properties" игнорируется? Пробовал Hibernate.initialize(), пробовал @Fetch(FetchMode.SELECT). Не помогает. Поле owner сериализуется нормально, но только за счет того, что я его явно запросил перед этим. Делать так для dependency не получится - там может быть все, что угодно, и заранее я не знаю, какие там могут быть поля.
Помогите, пожалуйста. Заранее благодарен.
276
21 октября 2010 года
Rebbit
1.1K / / 01.08.2005
Похоже это должно вам помочь
http://www.rzhevskiy.info/journal/dima/entry/hibernate_proxy_instance_of_not

Но я не уверен пойдет ли оно вниз по структуре и дотянет ли поля внутри самого dependency
32K
21 октября 2010 года
LLIbIcpEP
32 / / 06.07.2008
Дело в том, что dependency сам по себе может быть любым наследником Unit, и у него могут быть свои поля с типом какого-нибудь наследника Unit. Пока решил проблему такими костылями:
Код:
public static <T extends Unit> T loadUnitFields(T unit) throws ApiException {
        Hibernate.initialize(unit);
        Class<? extends Unit> clasz = unit.getClass();
        while (true) {
            Field[] tmp = clasz.getDeclaredFields();
            for (Field field : tmp) {
                try {
                    if (Unit.class.isAssignableFrom(field.getType())) {
                        field.setAccessible(true);
                        Unit thisUnit = (Unit) field.get(unit);
                        if (thisUnit != null) {
                            thisUnit = DataRepositoryProducer.findUnit(Unit.class, thisUnit.getId());
                            field.set(unit, loadUnitFields(thisUnit));
                        }
                    }
                } catch (Exception e) {
                    throw new ApiException(e);
                }
            }
            if (clasz.equals(Unit.class)) {
                break;
            } else {
                clasz = (Class<? extends Unit>) clasz.getSuperclass();
            }
        }
        return unit;
    }

Это конечно костыли, при том не самые изящные.
Все таки интересно, почему игнорируется "fetch all properties". Ведь в документации написано, что это как-раз и служит для моей цели. Или оно опять-же не работает рекурсивно? Не грузит поля полей? Но я не вижу разницы в возвращаемых данных без и с "fetch all properties".
Очень хочется решить проблему правильно, средствами хибера. Но если что, укажите хотя-бы на ошибки в костылях...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог