Используя JPA2 / Hibernate, я создал объект A, который имеет однонаправленное отображение на объект X (Смотри ниже). Внутри A у меня также есть временный член «t», который я пытаюсь вычислить с помощью метода @PostLoad. Для вычисления требуется доступ к ассоциированным X:
@Entity
public class A {
// ...
@Transient
int t;
@OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)
private List listOfX;
@PostLoad
public void calculateT() {
t = 0;
for (X x : listOfX)
t = t + x.someMethod();
}
}
Однако, когда я пытаюсь загрузить этот объект, я получаю ошибку «org.hibernate.LazyInitializationException: недопустимый доступ к загрузке коллекции».
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentBag.get(PersistentBag.java:445)
at java.util.Collections$UnmodifiableList.get(Collections.java:1154)
at mypackage.A.calculateT(A.java:32)
Просмотр спящего режима ' 2) В коде Hibernate есть явная проверка для предотвращения инициализации срочно загруженной коллекции во время @PostLoad:
protected final void initialize(boolean writing) {
if (!initialized) {
if (initializing) {
throw new LazyInitializationException("illegal access to loading collection");
}
throwLazyInitializationExceptionIfNotConnected();
session.initializeCollection(this, writing);
}
}
Единственный способ, которым я думаю исправить это, - это прекратить использование @PostLoad и переместить код инициализации в getT () аксессор, добавляющий синхронизированный блок. Однако я хочу этого избежать.
Итак, есть ли способ выполнить активную выборку до вызова @PostLoad? Я не знаю, как это сделать в JPA, поэтому я надеюсь, что есть кое-что, чего я не знаю.
Кроме того, может быть, проприетарный API Hibernate может что-то контролировать?