org.hibernate.LazyInitializationException - 无法初始化代理 - 没有会话

 小力维2010_622_531 发布于 2023-01-29 12:02

我得到以下异常:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at sei.persistence.wf.entities.Element_$$_jvstc68_47.getNote(Element_$$_jvstc68_47.java)
    at JSON_to_XML.createBpmnRepresantation(JSON_to_XML.java:139)
    at JSON_to_XML.main(JSON_to_XML.java:84)

当我尝试从main调用以下行时:

Model subProcessModel = getModelByModelGroup(1112);
System.out.println(subProcessModel.getElement().getNote());

getModelByModelGroup(int modelgroupid)首先实现了这个方法,如下所示:

public static Model getModelByModelGroup(int modelGroupId, boolean openTransaction) {

    Session session = SessionFactoryHelper.getSessionFactory().getCurrentSession();     
    Transaction tx = null;

    if (openTransaction) {
        tx = session.getTransaction();
    }

    String responseMessage = "";

    try {
        if (openTransaction) {
            tx.begin();
        }
        Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
        query.setParameter("modelGroupId", modelGroupId);

        List modelList = (List)query.list(); 
        Model model = null;

        for (Model m : modelList) {
            if (m.getModelType().getId() == 3) {
                model = m;
                break;
            }
        }

        if (model == null) {
            Object[] arrModels = modelList.toArray();
            if (arrModels.length == 0) {
                throw new Exception("Non esiste ");
            }

            model = (Model)arrModels[0];
        }

        if (openTransaction) {
            tx.commit();
        }

        return model;

   } catch(Exception ex) {
       if (openTransaction) {
           tx.rollback();
       }
       ex.printStackTrace();
       if (responseMessage.compareTo("") == 0) {
           responseMessage = "Error" + ex.getMessage();
       }
       return null;
    }
}

得到了例外.然后一位朋友建议我总是测试会话并获取当前会话以避免此错误.所以我这样做了:

public static Model getModelByModelGroup(int modelGroupId) {
    Session session = null;
    boolean openSession = session == null;
    Transaction tx = null;
    if (openSession) {
        session = SessionFactoryHelper.getSessionFactory().getCurrentSession(); 
        tx = session.getTransaction();
    }
    String responseMessage = "";

    try {
        if (openSession) {
            tx.begin();
        }
        Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
        query.setParameter("modelGroupId", modelGroupId);

        List modelList = (List)query.list(); 
        Model model = null;

        for (Model m : modelList) {
            if (m.getModelType().getId() == 3) {
                model = m;
                break;
            }
        }

        if (model == null) {
            Object[] arrModels = modelList.toArray();
            if (arrModels.length == 0) {
                throw new RuntimeException("Non esiste");
            }

            model = (Model)arrModels[0];

            if (openSession) {
                tx.commit();
            }
            return model;
        } catch(RuntimeException ex) {
            if (openSession) {
                tx.rollback();
            }
            ex.printStackTrace();
            if (responseMessage.compareTo("") == 0) {
                responseMessage = "Error" + ex.getMessage();
            }
            return null;        
        }
    }
}

但仍然得到相同的错误.我一直在阅读这个错误,并找到了一些可能的解决方案.其中一个是将lazyLoad设置为false但我不允许这样做,这就是为什么我被建议控制会话

8 个回答
  • 如果你使用Spring将类标记为@Transactional,那么Spring将处理会话管理.

    @Transactional
    public class MyClass {
        ...
    }
    

    通过使用@Transactional,可以自动处理许多重要方面,例如事务传播.在这种情况下,如果调用另一个事务方法,则该方法可以选择加入正在进行的事务,避免"无会话"异常.

    2023-01-29 12:03 回答
  • 这里的错误是您的会话管理配置设置为在提交事务时关闭会话.检查您是否有类似的东西:

    <property name="current_session_context_class">thread</property>
    

    在您的配置中.

    为了克服这个问题,您可以更改会话工厂的配置或打开另一个会话,而不仅仅是要求那些延迟加载的对象.但我在这里建议的是在getModelByModelGroup本身初始化这个惰性集合并调用:

    Hibernate.initialize(subProcessModel.getElement());
    

    当你还在活跃的会话中.

    最后一件事.友好的建议.你的方法中有这样的东西:

    for (Model m : modelList) {
        if (m.getModelType().getId() == 3) {
            model = m;
            break;
        }
    }
    

    请注意这段代码只是在查询语句中过滤那些类型id等于3的模型,只需要几行.

    更多阅读:

    会话工厂配置

    关闭会话的问题

    2023-01-29 12:03 回答
  • 处理的最好方法LazyInitializationException是使用JOIN FETCH指令:

    Query query = session.createQuery(
        "from Model m " +
        "join fetch m.modelType " +
        "where modelGroup.id = :modelGroupId"
    );
    

    无论如何,不​​要使用以下一些答案所建议的反模式:

    在视图中打开会话

    hibernate.enable_lazy_load_no_trans

    有时,DTO投影是比获取实体更好的选择,这样,你就不会得到任何实体LazyInitializationException.

    2023-01-29 12:03 回答
  • 你可以尝试设置

    <property name="hibernate.enable_lazy_load_no_trans">true</property>
    

    在hibernate.cfg.xml或persistence.xml中

    这个属性要记住的问题在这里得到了很好的解释

    2023-01-29 12:03 回答
  • 对于下面的注释,我得到了一对多关系的相同错误.

    @OneToMany(mappedBy="department", cascade = CascadeType.ALL)
    

    添加fetch = FetchType.EAGER后更改如下,它对我有用.

    @OneToMany(mappedBy="department", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    

    2023-01-29 12:03 回答
  • 如果你使用spring data jpa,spring boot你可以在application.properties中添加这一行

    spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
    

    2023-01-29 12:05 回答
  • 这个例外因为你打电话session.getEntityById(),会话将被关闭.因此,您需要将实体重新附加到会话中.或者Easy解决方案只是配置default-lazy="false" 为您entity.hbm.xml或者如果您使用注释只是添加@Proxy(lazy=false)到您的实体类.

    2023-01-29 12:05 回答
  • 我遇到了同样的问题。我认为解决此问题的另一种方法是,您可以按以下方式更改查询以加入从模型中获取元素的联接:

    Query query = session.createQuery("from Model m join fetch m.element where modelGroup.id = :modelGroupId")
    

    2023-01-29 12:06 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有