jFrenetic
jFrenetic

Reputation: 5542

Why is LazyInitializationException happening here?

So I have this entity with FetchType.LAZY collection:

@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;

}

And I have the following services:

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;
    }

}

Now, I'm trying to call ServiceB#load from CDI bean like this:

@Named
@SessionScoped
public class void WebController implements Serializable {

    @EJB        
    private ServiceC service;

    public void loadEntity(Long entityId) {
        service.load(entityId);
    }
}

But when I get to ServiceC entity.getLazyCollection.isEmpty() call, I get LazyInitializationException: illegal access to loading collection. I don't get it why.

Does it mean that after loading, entity somehow became detached?

I even tried to override ServiceA#loadEntity method in ServiceC to call entity.getLazyCollection() to trigger actual loading from database, but I still get this LazyInitializationException.

Upvotes: 3

Views: 449

Answers (1)

jFrenetic
jFrenetic

Reputation: 5542

The underlying exception was EntityNotFoundException.

OtherEntity has a mandatory one-to-one association with SomeOtherEntity, which wasn't found in the database. I didn't see it in logs, because logging in our project wasn't set up properly. Other than that, LazyInitializationException seems to be weird in this case. Looks like Hibernate wraps EntityNotFoundException into LazyInitializationException. The reason for doing this isn't clear for me.

Upvotes: 1

Related Questions