Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate LazyInitializationException while using collection in Spring JSP page

I have entities like this:

@Entity
@Table(name = "ASSESSMENT")
public class Assessment {

    //All other fields..

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "assessment")
    @OrderBy(value = "order ASC")
    private List<AssessmentPart> assessmentParts = new LinkedList<>();

    public List<AssessmentPart> getAssessmentParts() {
        return assessmentParts;
    }

    //All other getters/setters
}

The other one:

@Entity
@Table(name = "ASSESSMENT_PART")
public class AssessmentPart {

    //All other fields

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ASSESSMENT_ID", nullable = false)
    private Assessment assessment;

    public Assessment getAssessment() {
        return assessment;
    }

    public void setAssessment(Assessment assessment) {
        this.assessment = assessment;
    }

    //All other getters/setters
}

Assessment parts are lazy loaded from assessment entity. I also have spring controller method which is Transactional and loads assessment part from the database:

@Transactional
public void doSomething(String partId, Map<String, Object> model) {

    AssessmentPart assessmentPart = //laods a part with entity manager
    Assessment assessment = assessmentPart.getAssessment(); //Getting the assessments

    model.put("assessmentParts", assessment.getAssessmentParts()); //adding all assessments parts into spring model map
}

Once I've added assessment parts into spring model map, they become available in my JSP page and I am using JSTL to loop through them:

<c:forEach var="assessmentPart" items="${assessmentParts}">
     //Not loading any lazy stuff, just getting an ID of assessment part
</c:forEach>

The exception is thrown from this JSP page:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: my.package.something.Assessment.assessmentParts, could not initialize proxy - no Session

How is this possible if this collection has already been loaded in a transaction? I am just trying to loop through, hibernate shouldn't be loading anything at this point, because it was already loaded. Why is this weird thing happening?

like image 675
user2219247 Avatar asked Dec 26 '22 20:12

user2219247


1 Answers

In the view the entitymanager is already closed and as such the elements in your collections fail to retrieve there properties. The code you wrote in the controller doesn't initialize the elements in the collection (it is a LAZY collection) but only the collection is initialized (not the elements inside it).

Either force the entitymanager to remain open by configuring the OpenEntityManagerInViewFilter in your web configuration.

Or change your controller code to include a call to Hibernate.initialize to properly initialize your collection.

@Transactional
public void doSomething(String partId, Map<String, Object> model) {

    AssessmentPart assessmentPart = //laods a part with entity manager
    Assessment assessment = assessmentPart.getAssessment(); //Getting the assessments
    Hibernate.initialize(assesment.getAssesmentParts()); // Init collection
    model.put("assessmentParts", assessment.getAssessmentParts()); //adding all assessments parts into spring model map
}

Either that or create a custom query which forces eager fetching of the collection.

like image 83
M. Deinum Avatar answered Dec 28 '22 11:12

M. Deinum