@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;
JPA, Hibernate, persistence, FetchType
Код:
Код:
@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;
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;
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();
"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 не получится - там может быть все, что угодно, и заранее я не знаю, какие там могут быть поля.
Помогите, пожалуйста. Заранее благодарен.
http://www.rzhevskiy.info/journal/dima/entry/hibernate_proxy_instance_of_not
Но я не уверен пойдет ли оно вниз по структуре и дотянет ли поля внутри самого dependency
Код:
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;
}
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".
Очень хочется решить проблему правильно, средствами хибера. Но если что, укажите хотя-бы на ошибки в костылях...