【发布时间】:2012-01-12 14:57:59
【问题描述】:
所以我有这个带有FetchType.LAZY 集合的实体:
@Entity
public class Entity implements Serializable {
@OneToMany(mappedBy = "entity", fetch=FetchType.LAZY)
private List<OtherEntity> lazyCollection;
//getters and setters
}
@Entity
public class OtherEntity implements Serializable {
@ManyToOne
@JoinColumn(name = "entity", nullable = false)
private Entity entity;
}
我有以下服务:
public class ServiceA implements Serializable {
public Entity loadEntity(Long entityId) {
return em.find(Entity.class, entityId);
}
}
public class ServiceB extends ServiceA {
public Map<? extends X, ? extends Y> load(Long entityId) {
Entity entity = loadEntity(entityId);
//play with entity and fill the map with required data
return prepareMap(entity, map);
}
//meant to be overriden in inheriting services
protected Map<? extends X, ? extends Y> prepareMap(Entity entity,
Map<? extends X, ? extends Y> map) { return map; }
}
@Stateless
public class ServiceC extends ServiceB {
@Override
protected Map<? extends X, ? extends Y> prepareMap(Entity entity,
Map<? extends X, ? extends Y> map) {
if (entity.getLazyCollection() != null
&& !entity.getLazyCollection.isEmpty()) {
// play with entity and put some other data to map
}
return map;
}
}
现在,我正尝试像这样从 CDI bean 调用 ServiceB#load:
@Named
@SessionScoped
public class void WebController implements Serializable {
@EJB
private ServiceC service;
public void loadEntity(Long entityId) {
service.load(entityId);
}
}
但是当我接到 ServiceC entity.getLazyCollection.isEmpty() 电话时,我接到了LazyInitializationException: illegal access to loading collection。我不明白为什么。
这是否意味着加载后,实体以某种方式分离?
我什至试图覆盖ServiceC 中的ServiceA#loadEntity 方法以调用entity.getLazyCollection() 来触发从数据库的实际加载,但我仍然得到这个LazyInitializationException。
【问题讨论】:
-
你在使用 JTA EntityManager 吗?
-
不确定,我认为它是由 Hibernate 实现的,因为持久化提供程序是
Hibernate。 -
你是如何获得
EntityManager的? -
通过@PersistenceContext 注释(以及配置为使用
Hibernate作为持久性提供程序的persistence.xml)。 -
嗯,这似乎很奇怪,因为您使用的是 JTA 容器管理的 EntityManager。您应该处于由 ServiceC#load(-) 方法调用启动的活动事务中,并且可以访问该集合。