正确使用hibernate填充数据

时间:2017-01-09 22:00:36

标签: java mysql hibernate

我有一个设备表,我试图填充数据。该表有一个自动增量ID和一个制造商列。

我将所有制造商数据存储在名为manufacturerList的列表中。

然后我循环遍历整个列表,并为每个条目创建一个具有该条目的新Equipment对象并存储在变量temp中。在同一个循环中,我尝试使用hibernate session将temp保存到我的表中。

然而,当我运行这个时,我收到此错误

  

java.lang.IllegalStateException:Session / EntityManager已关闭

使用hibernate时实现此循环的正确方法是什么?

    SessionFactory factory = new Configuration()
            .configure("hibernate.cfg.xml")
            .addAnnotatedClass(Equipment.class)
            .buildSessionFactory();

    Session session = factory.getCurrentSession();

            try{
                   List<String> manufacturerList = new List<String>();
                   //populate the list here
                   //...

                    for (String manufacturer:manufacturerList) {
                        System.out.println(manufacturer);
                        Equipment temp = new Equipment(manufacturer);
                        session.beginTransaction();
                        session.save(temp);
                        session.getTransaction().commit();
                    }

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                factory.close();
            }

感谢。

2 个答案:

答案 0 :(得分:1)

在循环范围内插入和删除东西,我相信使用Session正确排序hibernate的这个特定实现,以确保会话不会过早关闭,如下所示:

        SessionFactory factory = new Configuration()
               .configure("hibernate.cfg.xml")
               .addAnnotatedClass(Equipment.class)
               .buildSessionFactory();

        Session session = factory.getCurrentSession();

        try{
               List<String> manufacturerList = new List<String>();
               //populate the list here
               //...

                session.beginTransaction();
                for (String manufacturer:manufacturerList) {
                    System.out.println(manufacturer);
                    Equipment temp = new Equipment(manufacturer);
                    session.save(temp);
                }
                session.getTransaction().commit();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            factory.close();
        }

应在将任何内容保存到会话之前启动事务。在完成所有保存后,交易将被提交。

更改为此后,程序运行时没有错误。

如果有任何我遗漏或可以优化的内容,请随时告诉我。

答案 1 :(得分:0)

您没有显示如何获得session值。显然,您拥有的session已关闭,或者从未正确打开过,但您的代码部分未显示。此外,您还会显示factory的结束,但该变量不会显示在您显示的代码段中。

通常,您可以长时间保留EntityManagerFactory,但EntityManager个实例的生命周期应该相当短。不要将实体管理器(或Session)重用于多个会话;在每一个之后杀死它并在需要时开始一个新的。这样可以更容易地推断开放或关闭的内容,并防止臭名昭着的会话溢出。

我们必须假设Equipment是一个正确声明和管理的实体类型,因为这里没有显示,并且似乎与您的错误消息无关。

因此,实现循环的正确方法是在具有循环的类中的某处初始化EntityManager,将其用于循环,并在循环后的某个时间关闭它,但是要离开{{ 1}}到它自己的逻辑流程。

另外,你没有填写一张桌子&#34;使用Hibernate或任何JPA解决方案。 Hibernate / JPA用于对象模型,而不是表模型。将您的实体类型写为对象类型(无人工&#34; ID&#34;关键字段!)。让JPA处理映射而不是代码执行它。想想对象,而不是表格。

使用JDBC比使用JPA更好地完成批量操作。 JPA用于建模实体,而不是管理数据。