1

Here's where I'm stuck:

javax.servlet.ServletException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: it.trew.model.TipoCaratteristica.traduzioni, no session or session was closed

Some of my entities code:

@Entity
@Table(name = "tipi_caratteristiche")
public class TipoCaratteristica implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    private String nome;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(
        name = "tipi_caratteristiche_traduzioni", 
        joinColumns = { @JoinColumn(name = "tipo_caratteristica_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "traduzione_id") }
    )
    private List<Traduzione> traduzioni = new ArrayList<Traduzione>();

"Traduzione" is a simple plain entity with a pair of String properties.

I have an "edit" jsf page which loads a "TipoCaratteristica" by id and try to show its List in a tag.

I use an ejb-facade method for fetching the edited object:

public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

Then, in the jsf backing bean:

TipoCaratteristica tc = ejbFacade.find(Long.valueOf(value));

I read something about that exception. Actually, setting fetch type EAGER on the "traduzioni" collection fix it but I don't want to. I read about doing all in a transaction, or using Hibernate.initialize() but don't know how to do that.

Can you help me please?

2 Answers 2

2
@Override
public TipoCaratteristica find(Object id) {
    TipoCaratteristica result = super.find(id);
    Hibernate.initialize(result.getTraduzioni());
    return result;
}

Or instead of using em.find(), use a query that will load everything is a single query:

select distinct tc from TipoCaratteristica 
left join fetch tc.traduzioni
where tc.id = :id
Sign up to request clarification or add additional context in comments.

3 Comments

You seem to have a base parameterized class for your EJB facades, and one subclass of this EJB facade for every entity. The above overridden method should be in the EJB facade for the TipoCaratteristica entity. If my assumptions are wrong, then post your code.
ok. I have to remember that initialize() has to be done inside EJB methods hasn't it?
It has to be done in a place where the session is still open, inside the transaction. If you do it once the session is closes, you will obviously get the same lazy loading exception.
2

You could resolve this using PersistentContext.EXTENDED Attribute in your entity manager.

Example:

@PersistentContext(type=PersistentContext.EXTENDED)
private EntityManager em; 

or in newer versions:

@PersistentContext(type=PersistentContextType.EXTENDED)
private EntityManager em; 

This error happens because for every transaction the entity manager transaction is closed, this attribute avoids this and allows the entity manager stay available. You could read more detail reading Seam in Action book of Dan Allen, he explains this issue in detail.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.