我在奇怪的条件下面对懒惰的初始化。
事务:合并持久对象。然后坚持下去 非持久对象抛出异常。
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.)
}
拥有的GeoObjects和创建者可以由用户创建或者找到并添加到列表中作为存在(持久)。所有存在的和用户创建的实体都存储在事务(人员字段)之间的有状态bean中。并完全取得了他们分开的交易。然后,所有结构的持久化来自commitPerson():
@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);
}
}
}
}
如果其中一个拥有的GeoObject是持久的而另一个不是。
,则抛出异常at ru.vetrf.cerberus.ejb.GeoObjectManager.addGeoObject(GeoObjectManager.java:119)
这一行是
addressManager.addAddress(geoObject.getAddress());
在持久性GeoObject的更新(合并)之后,似乎会话已经消失(对于非持久性GeoObject及其地址)。为什么会这样? 其他场景(一个存在,一个新的,多个存在的,多个新的)传递良好。 创始人名单不受此问题的影响。
P.S。可以认为添加/更新方法仅包含持久化/合并。
答案 0 :(得分:1)
这是问题,您在事务之间移动具有未初始化代理的对象。这就是抛出这样的错误的地方:当你访问代理服务器(例如带有延迟加载的列表)时,当加载对象的事务被关闭时。
考虑一下你是否真的需要延迟加载,如果是这样,请确保在关闭事务之前加载所有代理(例如,person.getOwners()。size())