failed to lazily initialize a collection
blabno Jan 27, 2008 7:51 AMI have stateless bean (LocationBean) that provides access to data, and stateful action bean (CountryEditorBean) that has reference to stateless bean (Local interface). When I click a link on data table with list of entities that redirects me to page with edit form for that entity, I get exception that other aggregated entities cannot be fetched since session has been closed.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: pl.labno.bernard.bidbull.locations.Region.towns, no session or session was closed
So I figure that LocationBean fetches list of entities, and closes session (but why?), or detatches that entities. They exist only in some seam context.
Then on editCountry.jspx there is an attempt to count number of Regions aggregated in that country entity. This causes the error, I think, since by default relations are lazy fetched.
Is my interpretation correct ?
I do not want to change fething policy, so what can I do to make things work ? Cutting LocationBean out is not an option for me.
@Stateless public class LocationBean implements LocationLocal { @PersistenceContext private EntityManager em; public void add(Country country) throws NonUniqueObjectException { if (em.find(Country.class, country.getId()) == null) { em.persist(country); } else { throw new NonUniqueObjectException(country.getId(), Country.class.getCanonicalName()); } } public void add(Region region) { em.persist(region); } public void add(Town town) { em.persist(town); } public void update(Country country) { em.merge(country); } public void update(Region region) { em.merge(region); } public void update(Town town) { em.merge(town); } public void remove(Country country) { em.remove(country); } public void remove(Region region) { em.remove(region); } public void remove(Town town) { em.remove(town); } public List<Country> getCountries() { return em.createNamedQuery(Country.GET_COUNTRIES_QUERY).getResultList(); } }
@Name("countryEditor") @Scope(ScopeType.CONVERSATION) @Stateful public class CountryEditorBean implements CountryEditorLocal { @In @Out private Country country; @EJB private LocationLocal locationBean; private Boolean error = false; @Begin(pageflow = "editCountry") public void editCountry() {} public void save() { locationBean.update(getCountry()); } public Country getCountry() { return country; } public void setCountry(Country country) { this.country = country; } @Remove public void destroy() {} }