Hibernate LazyInitializationException while using collection in Spring JSP page

后端 未结 3 1430
灰色年华
灰色年华 2020-12-03 19:51

I have entities like this:

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

    //All other fields..

    @OneToMany(fetch = FetchType.LAZY,          


        
相关标签:
3条回答
  • 2020-12-03 20:01

    Loading AssessmentPart from EntityManager will Load Assessment @ManyToOne(fetch = FetchType.EAGER)

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

    Trying to extract AssessmentParts from assessment wont work since it's not @OneToMany(fetch = FetchType.LAZY) and session is already closed

    model.put("assessmentParts", assessment.getAssessmentParts());
    

    Get list of AssessmentParts by Assessment from EntityManager in new method should solve the problem.

    0 讨论(0)
  • 2020-12-03 20:16

    Change

    model.put("assessmentParts", assessment.getAssessmentParts());
    

    to

    Hibernate.initialize(assessment.getAssessmentParts());
    

    to initialize your collection.

    The method call assessment.getAssessmentParts() is not initializing your collection. This method call will just return you a collection wrapper and this wrapper you need to pass to the Hibernate.initialize method for manual initialization.

    EDIT:

    With JPA, you can fetch the AssessmentParts along with the Assessment (wherever needed) using JPQL Fetch Joins, overriding the default behavior:

    SELECT a FROM Assessment asmt LEFT JOIN FETCH asmt.assessmentParts WHERE asmt.id = :id
    
    0 讨论(0)
  • 2020-12-03 20:22

    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.

    0 讨论(0)
提交回复
热议问题