当前位置: 首页 > 知识库问答 >
问题:

Spring MVC,Hibernate:延迟初始化异常

司徒元明
2023-03-14

我正在开发一个Spring-MVC应用程序,其中我有3个类,组扫描,组节,组注释。组扫描器具有与组节的一对多映射,组节与组注释具有一对多映射。我正在尝试根据 GroupCanvas 的主键检索注释,但我收到Hibernate延迟初始化异常。我在网上尝试了这些建议,主要是SO,但似乎没有帮助。这是代码。

DAO 方法抛出错误:

 @Override
    public List<GroupNotes> searchNotesByDays(int days, int mcanvasid) {
        Session session = this.sessionFactory.getCurrentSession();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, -days);
        long daysAgo = cal.getTimeInMillis();
        Timestamp nowMinusDaysAsTimestamp = new Timestamp(daysAgo);
        Query query = session.createQuery("from GroupSection as n where n.currentcanvas.mcanvasid=:mcanvasid");
        query.setParameter("mcanvasid", mcanvasid);
        List<GroupSection> sectionList = query.list();
        List<GroupNotes> notesList = new ArrayList<GroupNotes>();
        for (GroupSection e : sectionList) {
            Query query1 = session.createQuery("from GroupNotes as n where n.ownednotes.msectionid=:msectionid and n.noteCreationTime >:limit");
            query1.setParameter("limit", nowMinusDaysAsTimestamp);
            query1.setParameter("msectionid",e.getMsectionid());
            notesList.addAll(query1.list());
        }
        return notesList;
    }

GroupCanvas模型:

@Entity
@Table(name = "membercanvas")
public class GroupCanvas{

variables, getters, setters ignored
    @OneToMany(mappedBy = "currentcanvas",fetch=FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JsonIgnore
    private Set<GroupSection> ownedsection = new HashSet<>();

    public Set<GroupSection> getOwnedsection() {
        return this.ownedsection;
    }

    public void setOwnedsection(Set<GroupSection> ownedsection) {
        this.ownedsection = ownedsection;
    }
}

组段模型类:

@Entity
@Table(name = "membersection")
public class GroupSection {
 @ManyToOne
    @JoinColumn(name = "groupcanvasid",nullable = false)
    @JsonIgnore
    private GroupCanvas currentcanvas;

    public GroupCanvas getCurrentcanvas() {
        return this.currentcanvas;
    }

    public void setCurrentcanvas(GroupCanvas currentcanvas) {
        this.currentcanvas = currentcanvas;
    }

    public int getCurrentCanvasId(){
        return this.currentcanvas.getMcanvasid();
    }


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

    public Set<GroupNotes> getSectionsnotes(){
        return this.sectionsnotes;
    }

    public void setSectionsnotes(Set<GroupNotes> sectionsnotes){
        this.sectionsnotes=sectionsnotes;
    }
}

群注释:

@Entity
@Table(name="groupnotes")
public class GroupNotes{
   @ManyToOne
    @JoinColumn(name = "msectionid")
    @JsonIgnore
    private GroupSection ownednotes;

    public GroupSection getOwnednotes(){return this.ownednotes;}

    public void setOwnednotes(GroupSection ownednotes){this.ownednotes=ownednotes;}
}

错误日志:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.journaldev.spring.model.GroupCanvas.ownedsection, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownednotes"]->com.journaldev.spring.model.GroupSection["currentcanvas"]->com.journaldev.spring.model.GroupCanvas["ownedsection"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.journaldev.spring.model.GroupCanvas.ownedsection, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.journaldev.spring.model.GroupNotes["ownednotes"]->com.journaldev.spring.model.GroupSection["currentcanvas"]->com.journaldev.spring.model.GroupCanvas["ownedsection"])
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:256)

我做错了什么,请告诉我。如果需要更多信息,请发表评论。

共有1个答案

松元明
2023-03-14

JSON 转换器在Hibernate会话完成后执行。JSON转换器正在盲目地访问所有获取器和设置器,甚至是懒惰的获取器和设置器。因此,当Hibernate尝试初始化组扫描#拥有部分时,没有可用的会话,因此会引发此异常。

可能的解决方案:

>

  • 不要直接在Hibernate托管对象上执行JSON转换器。创建DTO对象来完成这项工作。DTO对象没有逻辑,是纯java bean,非常适合这个角色。但是缺点是你必须维护另一个类层次结构。利大于弊。以下帖子可以帮助这种方法:

    DTO模式:在两个对象之间复制属性的最佳方式

    使用注释将某些字段标记为不可序列化。例如,JsonIgnore。这样做的缺点是,如果在不同的API中需要此字段,则不能使用此字段。

    如果可以从您的模型中删除一个反向参考(注释-

  •  类似资料:
    • 7.4.4 延迟初始化的bean 默认情况下,ApplicationContext实现在初始化过程中随即创建和配置所有单例bean。一般来说,这种预实例化是可取的,因为可以立即发现配置或周围环境中的错误,而不是在几个小时甚至几天以后。当这种行为不可取时,可以通过将bean定义标记为延迟初始化来阻止预实例化。延迟初始化的bean告诉IoC容器,当bean首次被请求时而不是在启动时创建一个实例。 在X

    • 问题内容: 在我的JavaFX应用程序中,当我对EmbeddedId类使用“ 非延迟收集” 选项时,为了保持双向关系,它将产生以下异常。经过几个小时的工作后,我仍然无法解决它。实体类如下。谢谢。 EmbeddedId类 WorkflowStep实体 (带有EmbeddedId) WfScriptTemplate实体 (具有双向关系) PostgreSQL异常 MySQL异常 问题答案: 摘录自JP

    • 问题内容: 我有以下提到的实体类,当我执行我的应用程序时,我得到了以下异常。其他一些类似的问题也不能解决问题。 我该如何解决这个问题? Emp实体 部门实体 DAOImpl 泽西岛RESTful服务 springapplicationContext.xml 问题答案: 我已通过在web.xml中添加以下内容解决了该问题 在这里和这里礼貌 谢谢

    • 问题内容: 我想延迟控制器的初始化,直到从服务器收到必要的数据为止。 我找到了针对Angular1.0.1的解决方案:延迟AngularJS路由更改,直到加载模型以防止闪烁,但无法使其与Angular1.1.0一起使用 模板 ​ JavaScript http://jsfiddle.net/dTJ9N/1/ 问题答案: 由于$ http返回了promise,因此创建自己的deferred仅在htt

    • 我在对象中使用Hibernate,即使会话未关闭,也会得到lazyinitializationexception。 以下是争议对象之间的关系。有3个对象: 目标A 对象B 对象C ObjectA包括ObjectB作为FetchType=EAGER ObjectB包括ObjectC作为FetchType=LAZY 我们正在获取ObjectA。因此,由于急切获取类型,它会自动获取ObjectB。但是当

    • 问题内容: 我有这个问题: org.hibernate.LazyInitializationException:无法延迟初始化角色集合:mvc3.model.Topic.comments,没有会话或会话被关闭 这是模型: 调用模型的控制器如下所示: jsp页看起来如下所示: 查看jsp时会引发异常。与 c:forEach 循环一致 问题答案: 如果您知道每次检索a 都想查看全部,则将字段映射更改为