【问题标题】:Why is LazyInitializationException happening here?为什么这里会发生 LazyInitializationException?
【发布时间】: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(-) 方法调用启动的活动事务中,并且可以访问该集合。

标签: hibernate jpa-2.0 ejb-3.1


【解决方案1】:

基础异常是EntityNotFoundException

OtherEntitySomeOtherEntity 具有强制性的一对一关联,但在数据库中未找到该关联。我没有在日志中看到它,因为登录我们的项目没有正确设置。除此之外,LazyInitializationException 在这种情况下似乎很奇怪。看起来 Hibernate 将 EntityNotFoundException 包装成 LazyInitializationException。我不清楚这样做的原因。

【讨论】:

  • Hibernate 的神秘偏差之一 ;-)
猜你喜欢
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多