我得到以下异常:

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)

当我试图从主要呼叫以下线路:

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<Model> modelList = (List<Model>)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<Model> modelList = (List<Model>)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,但我不允许这样做,这就是为什么我被建议控制会话


当前回答

对于下面的注释,我得到了相同的一对多关系错误。

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

增加fetch=FetchType后更改如下。渴望,它对我有效。

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

其他回答

你可以试着设置

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

在hibernate.cfg.xml或persistence.xml中

这里已经很好地解释了这个性质需要记住的问题

这里的问题是您的会话管理配置设置为在提交事务时关闭会话。检查一下你是否有这样的东西:

<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的模型。

更多阅读:

会话工厂配置

闭门会议的问题

我也遇到过同样的问题。我认为另一种解决这个问题的方法是,你可以改变查询,从模型中获取你的元素,如下所示:

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

如果你正在使用Grail的框架,通过在域类的特定字段上使用lazy关键字来解决惰性初始化异常是很简单的。

例如:

class Book {
    static belongsTo = [author: Author]
    static mapping = {
        author lazy: false
    }
}

在这里查找更多信息

所有关于添加JOIN FETCH(或左JOIN FETCH)的答案都是正确的,我只想添加这个: 如果你有转换器,请确保getAsObject子使用一个“查找”,而不是包括在sql Join Fetch太。 我花了很多时间来修复一个类似的问题,问题是在转换器。