1

I though I understood lazy/eager loading, but obviously I don't:

I have a service that is marked @Transactional, yet when I try to manipulate the list I get (accessing its objects), I get "org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: tld.myproduct.data.entities.CategoryType.translatableText, no session or session was closed". Any suggestions to why I cannot access my under-objects?

UPDATE: The exception happens at the line "type.getTranslatableText().size()"

Cheers

Nik

// The service
@Service("categoryTypeService")
@Transactional("transactionManager")
public class CategoryTypeServiceImpl extends AbstractCRUDServiceImpl<CategoryType, Integer> implements CategoryTypeService {

    @SuppressWarnings("unchecked")
    @Override
    public List<CategoryType> getAll() {
        List<CategoryType> list = DAO.getSession().createCriteria(CategoryType.class).list();

        for(CategoryType type : list)   
            type.getTranslatableText().size();  // Access TranslatableText to demonstrate problem

        return list;
    }

}


// The entity
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
@Configurable(preConstruction=true)
public class CategoryType {

    @Id
    @Column(nullable = false)
    private Integer id;

    @Column(length = 50, nullable = true)
    private String description;

    @Column(name = "TranslatableDescriptionId", nullable = false)
    private Integer TranslatableDescriptionId;

    @OneToMany(fetch=FetchType.LAZY)
    @JoinColumn(name = "Id", referencedColumnName="TranslatableDescriptionId", insertable=false, updatable=false)
    private Set<TranslatableText> translatableText;

    /** getters and setters **/
}
2
  • 1
    How is your DAO.getSession() method implemented? Commented Sep 15, 2010 at 10:18
  • WaxWing: return ((SessionFactory) sessionFactory).getCurrentSession(); Commented Sep 16, 2010 at 7:54

1 Answer 1

2

Here is a general discussion of Open Session in View issue. I recommend you to read the article.

To put is simple, you have 3 possible solutions:

1) don't do lazy loading of the collection (of course, if it's not critical, performance should be tested somehow):

@OneToMany(fetch=FetchType.EAGER)   //   <-- it's not lazy any more
@JoinColumn(name = "Id", referencedColumnName="TranslatableDescriptionId", insertable=false, updatable=false)
private Set<TranslatableText> translatableText;

2) you can use Open Session in View Filter (or OpenEntityManagerInViewFilter), but this will keep your session open until the page loading will be finished (maybe a few seconds).

It can cause performance issues, and more likely, you'll get the situation, when one user is changing objects while another user has an open hibernate session. I don't know exactly what happens then but you should find it out if you want to be sure that your application is robust.

3) when you need to load some collection from a DB just execute a JPA query and fetch all the necessary data with special DAO method (this means that field translatableText will disappear from CategoryType class). The most robust solution but you'll need to do some extra work to implement it, its more difficult then any of previous 2 options.

Sign up to request clarification or add additional context in comments.

1 Comment

Suggestion #1 was revealing as it caused other errors. It seems Hibernate takes offence at how many places I use this translatableText, so I need to sort that out, and that's most likely the story behind this weird error. So suggestion #2 is probably involved as, with lazy loading, it's already been loaded other places before. I'm not a big fan of suggestion #3, though, as it seems to me that defeats much of the purpose of using JPA in the first place, or have I misunderstood you?

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.