我遇到了具有奇怪條件的懶惰初始化。休眠會話已不存在
- 事務:獲取持久對象的底層實體。
- 事務:獲取非持久對象的底層實體。
事務:合併一個持久對象。然後堅持 一個不持久化的對象拋出一個異常。
javax.persistence.PersistenceException:org.hibernate.LazyInitializationException:無法初始化代理 - 沒有會話。
當堅持Person類的複雜對象時拋出。
public class Person {
protected List<Person> founders;
protected List<GeoObject> ownedGeoObjects;
}
public class GeoObject {
private List<Person> owners;
private Address address; //complex lazy-fetched structure of pre-defined persistent entities (country, city, etc.)
}
ownedGeoObjects和創始人可以由用戶創建或找到並添加到列表中作爲存在(持久性)。所有存在的和用戶創建的實體都存儲在事務之間的有狀態bean(人員字段)中。並完全取代他們分開的交易。然後堅持所有結構都來自commitPerson():如果ownedGeoObjects之一是持久的,另一種是不
@Stateful
public class SessionManager {
private Person person;
private Person commitPerson(Person person) {
personManager.addPerson(person);
commitFounders(person.getFounders());
commitGeoObjects(person);
return person;
}
private void commitFounders(List<Person> founders) throws ValidationError {
for (Person founder : founders) {
if (!founder.getPersistent()) {
personManager.addPerson(founder);
}
}
}
private void commitGeoObjects(Person person) throws ValidationError {
List<GeoObject> objects = person.getOwnedGeoObjects();
for (GeoObject geoObject : objects) {
refetch(geoObject); //this is my workaround
geoObject.getOwners().add(person); //inverse relation
if (!geoObject.getPersistent()) {
geoObjectManager.addGeoObject(geoObject);
} else {
geoObjectManager.updateGeoObject(geoObject);
}
}
}
}
拋出異常。
at ru.vetrf.cerberus.ejb.GeoObjectManager.addGeoObject(GeoObjectManager.java:119)
這條線是
addressManager.addAddress(geoObject.getAddress());
好像會話持久GeoObject的更新(合併)走了之後(一個不是永久GeoObject及其地址)。爲什麼會發生? 其他場景(一個存在,一個新的,多個存在,多個新)通過。 創始人名單不受此問題影響。
p.s.可以認爲添加/更新方法僅由持久/合併組成。
我沒有提到的是,收盤前每單獨轉換所有相關實體。但正如我所說的,當一個GeoObject實體持久化而另一個不持久時,問題就出現了。現在,作爲解決方法,我在每次添加/更新之前都會重新獲取GeoObject。 (我跳過它,GeoObject也有底層實體)。但我仍然不知道爲什麼我應該這樣做。 – user935629