【问题标题】:Spring, Hibernate : Lazy initialization exception for many-to-many mappingSpring,Hibernate:多对多映射的延迟初始化异常
【发布时间】:2016-06-16 11:57:09
【问题描述】:

我正在开发一个 Spring-MVC 应用程序,我在其中尝试为两个实体之间已经存在的一对多映射添加多对多映射。我们在项目中拥有的两个实体是GroupSectionGroupNotes

对于项目中的一项任务,我不得不在 GroupSection 和 GroupNotes 之间引入多对多映射,但我遇到了延迟初始化异常。

错误:

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"])

这里是被调用的控制器方法:

@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方法(Service方法只调用DAO方法):

   @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 模型:

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<>();
}

组笔记:

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<>();
}

我做错了什么?是否可以同时在两个类之间进行一对多和多对多映射。如果是,那么该错误是怎么回事。请告诉我。谢谢。 :-)

【问题讨论】:

  • 看来问题出在private Set&lt;GroupSection&gt; groupSections = new HashSet&lt;&gt;(); 上,您也可以尝试对这个对象进行 Eager 初始化吗?
  • @BandiKishore :我尝试的第一件事,也尝试了 JSONIgnore,没有帮助...
  • 你能试试github.com/FasterXML/jackson-datatype-hibernate 它在使用休眠和杰克逊的懒惰领域有帮助。
  • @BandiKishore :我使用的 JSONIgnore 来自 FasterXML。我还没有发布导入,现在添加它们。已添加。
  • 当您使用 Eager for "private Set groupSections = new HashSet();" 时出现什么错误或者当你使用@JsonIgnore

标签: java spring hibernate spring-mvc


【解决方案1】:

调用 listGroupSectionByCanvasid 时,您会打开一个事务和一个会话。当呼叫返回时,会话关闭。当 spring 返回值时,它会尝试读取您的对象,并且由于延迟加载您的多对多关系 groupNotesSet 和 groupSections 是需要会话的休眠集合。在您的情况下,会话不再存在。

【讨论】:

  • 是的,为此我已经尝试过 Eager 初始化和/或 JSONIgnore,没有任何帮助。
  • groupSections 相同。在您的代码中没有对 GroupSection 的渴望
  • 是的,在多对多映射的两边都急切加载。没有帮助...如果您愿意,我可以发布更新的课程。
猜你喜欢
  • 2016-05-14
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2014-03-21
相关资源
最近更新 更多