如何修复Java中的LazyInitializationException?

我从事一个小项目,我有2个表,用户和应用程序。一个用户可以有多个应用程序,一个应用程序可能由多个用户使用,因此它们是它们之间的多对多关系。每个表都有一些字段(id,名称,密码,技术等),我还在User和Apprause类中声明了2个数组列表,并带有@ManyToMany的注释。问题是,在我的业务层中,我写了一个方法,应该向用户添加一个应用程序,当我尝试做user.getListOfApplications().add(app)时,它会给我这个例外...


公共类管理器Hibernate { private SessionFactory sessionFactory;


public void setup()

{

     sessionFactory = new Configuration().configure().buildSessionFactory();

}


public void exit()

{

    sessionFactory.close();

}


public void create(Object obj)

{

    Session session = sessionFactory.openSession();

    session.beginTransaction();


    session.save(obj);


    session.getTransaction().commit();

    session.close();

}


public Object read(Class<?> c, int idObj)

{

    Session session = sessionFactory.openSession();

    session.beginTransaction();


    Object obj = session.get(c, idObj);


    System.out.println(obj);


    session.getTransaction().commit();

    session.close();

    return obj;

}


public void update(Object obj)

{

    Session session = sessionFactory.openSession();

    session.beginTransaction();


    session.update(obj);


    session.getTransaction().commit();

    session.close();

}


public void delete(Object obj)

{

    Session session = sessionFactory.openSession();

    session.beginTransaction();


    session.delete(obj);


    session.getTransaction().commit();

    session.close();

}


public <T> List<T> loadAllData(Class<T> type)

{

    Session session = sessionFactory.openSession();

    session.beginTransaction();


    CriteriaBuilder builder = session.getCriteriaBuilder();

    CriteriaQuery<T> criteria = builder.createQuery(type);

    criteria.from(type);

    List<T> data = session.createQuery(criteria).getResultList();


    session.getTransaction().commit();

    session.close();

    return data;

}

}


猛跑小猪
浏览 78回答 2
2回答

慕仙森

当您使用以下方法管理器加载数据时,问题开始。public <T> List<T> loadAllData(Class<T> type){&nbsp; &nbsp; &nbsp; &nbsp; // New session was opened here&nbsp; &nbsp; &nbsp; &nbsp; Session session = sessionFactory.openSession();&nbsp; &nbsp; &nbsp; &nbsp; session.beginTransaction();&nbsp; &nbsp; &nbsp; &nbsp; CriteriaBuilder builder = session.getCriteriaBuilder();&nbsp; &nbsp; &nbsp; &nbsp; CriteriaQuery<T> criteria = builder.createQuery(type);&nbsp; &nbsp; &nbsp; &nbsp; criteria.from(type);&nbsp; &nbsp; &nbsp; &nbsp; List<T> data = session.createQuery(criteria).getResultList();&nbsp; &nbsp; &nbsp; &nbsp; session.getTransaction().commit();&nbsp; &nbsp; &nbsp; &nbsp; session.close();&nbsp; &nbsp; &nbsp; &nbsp; //session is close here&nbsp; &nbsp; &nbsp; &nbsp; return data;&nbsp; &nbsp; }因此,当您加载数据时,休眠框架将仅加载用户对象。由于您已选择在模型类中使用延迟加载,因此只有在您尝试访问列表时才会加载应用程序值。由于您已经关闭了会话,因此框架无法再获取应用程序列表,从而导致延迟加载异常。listOfApplications = managerHibernate.loadAllData(Application.class);//loading user data and close the session associated with itlistOfUsers = managerHibernate.loadAllData(User.class);User user = null;Application app = null;for(Application index: listOfApplications){&nbsp; if(index.getApplicationName().equals(applicationName))&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; okApp = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app = index;&nbsp; &nbsp; &nbsp; }}for(User index: listOfUsers){&nbsp; if(index.getUserUserName().equals(userUserName))&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; okUser = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; user = index;&nbsp; &nbsp; &nbsp; }}if(okUser == 0&nbsp; || okApp == 0)&nbsp; return false;else{&nbsp; &nbsp;&nbsp; // when you run this line the hibernate framework will try to retrieve the application data.Since you have the closed session lazy load exception occurs&nbsp;&nbsp; user.getListOfApplications().add(app);&nbsp; return true;}解决此问题的方法1)尝试保持会话打开状态,以便您的框架可以获取应用程序数据2)在模型pojo类中将延迟加载更改为预先加载(因为您正在使用多对多关系,因此不建议以这种方式使用)

慕码人2483693

由于没有用于获取用户中应用程序的惰性列表的事务,因此您需要先获取它。为了做到这一点,你可以改变loadAllData,如下所示:public interface CriteriaSpec&nbsp;{public void joinFetch(CriteriaBuilder builder, CriteriaQuery criteria, Root root);}public <T> List<T> loadAllData(Class<T> type, Optional<CriteriaSpec> spec){Session session = sessionFactory.openSession();session.beginTransaction();CriteriaBuilder builder = session.getCriteriaBuilder();CriteriaQuery<T> criteria = builder.createQuery(type);Root root = criteria.from(type);if(spec.isPresent())&nbsp; &nbsp; spec.joinFetch(builder, criteria, root);List<T> data = session.createQuery(criteria).getResultList();session.getTransaction().commit();session.close();return data;}然后使用它:managerHibernate.loadAllData(Application.class, Optional.empty());listOfUsers = managerHibernate.loadAllData(User.class, (rootEntity, query,&nbsp;criteriaBuilder) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rootEntity.fetch("listOfApplications", JoinType.Left_OUTER_JOIN);&nbsp; &nbsp; &nbsp; &nbsp; });
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python