简体   繁体   中英

Spring, Hibernate : Lazy initialization exception for many-to-many mapping

I am working on a Spring-MVC application in which I am trying to add many-to-many mapping for an already existing one-to-many mapping between two entities. Two entities which we have in the project are GroupSection and GroupNotes .

For one of the task in project, I had to introduce a many-to-many mapping between GroupSection and GroupNotes, but I am getting a lazy initialization exception.

Error :

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: failed to lazily initialize a collection of role: com.tooltank.spring.model.GroupSection.groupSections, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.tooltank.spring.model.GroupSection["groupSections"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.tooltank.spring.model.GroupSection.groupSections, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.tooltank.spring.model.GroupSection["groupSections"])

Here is the controller method which was called:

@RequestMapping(value = "/sections/get/{canvasid}")
    public @ResponseBody List<GroupSection> getAllSectionsForCanvas(@PathVariable("canvasid") int canvasid) {
        boolean value = this.personService.getCanvasValuesForCanvas(canvasid);
        return this.groupSectionService.listGroupSectionByCanvasid(canvasid, value);
    }

DAO method(Service method just calls the DAO method) :

   @Override
    @Transactional(readOnly = true)
    public List<GroupSection> listGroupSectionByCanvasid(int mcanvasid) {
        try {
            Session session = this.sessionFactory.getCurrentSession();
            org.hibernate.Query query = session.createQuery("From GroupSection as msection where " +
                    "msection.currentcanvas.mcanvasid=:mcanvasid and msection.sectionDisabled=false and msection.sectionInActive=false");
            query.setParameter("mcanvasid", mcanvasid);
            return query.list();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

GroupSection model :

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;

import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "membersection")
public class GroupSection {


// Below is self-mapping, required for one of the task, works.
    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "owned_section_id", nullable = true)
    private GroupSection primarySection;

    @OneToMany(mappedBy = "primarySection", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private Set<GroupSection> groupSections = new HashSet<>();


// Many to many mapping, I had lazy loading before, but tried Eager to see if error goes, it doesn't. :

    @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
    @JoinTable(name = "sectionjunction",joinColumns = {@JoinColumn(name = "msectionid")},
            inverseJoinColumns = {@JoinColumn(name = "mnoteid")})
    private Set<GroupNotes> groupNotesSet = new HashSet<>();


// One to many mapping below :

@OneToMany(mappedBy = "ownednotes", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JsonIgnore
private Set<GroupNotes> sectionsnotes = new HashSet<>();
}

GroupNotes :

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;

import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "groupnotes")
public class GroupNotes implements Serializable {


    @JsonIgnore
    @ManyToMany(mappedBy = "groupNotesSet",fetch = FetchType.EAGER)
    private Set<GroupSection> groupSectionSet = new HashSet<>();

    @ManyToOne
    @JoinColumn(name = "msectionid",nullable = true)
    @JsonIgnore
    private GroupSection ownednotes;

 // Self mappings :


    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "owned_note_id", nullable = true)
    private GroupNotes primaryNote;

    @OneToMany(mappedBy = "primaryNote", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private Set<GroupNotes> groupNotesSet = new HashSet<>();
}

What am I doing wrong? Is it possible to simultaneously have one-to-many and many-to-many mapping between 2 classes. If yes, then what's the deal with that error. Kindly let me know. THank you. :-)

When calling listGroupSectionByCanvasid you open a transaction and a session. When the call return the session is closed. And when spring is returning the value it tries to read you object and because of lazy loading of your manytomany relation groupNotesSet and groupSections are hibernate collections that need the session. And in your case session doesn't exsit anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM