繁体   English   中英

使用休眠模式填充数据的正确方法

[英]Correct way to use hibernate to populate a table with data

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

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

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

但是,当我运行它时,出现此错误

java.lang.IllegalStateException:会话/实体管理器已关闭

在使用休眠模式时实现此循环的正确方法是什么?

    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();
            }

谢谢。

在从循环作用域中插入和删除事物的过程中,我相信使用Session来确保此特定的休眠实现的正确顺序如下,以确保不会过早关闭会话:

        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();
        }

在将任何内容保存到会话之前,应启动事务。 毕竟,应该保存交易。

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

请随时让我知道我是否缺少任何东西或可以优化的地方。

您没有显示如何获取session价值。 显然,您拥有的session已关闭,或者从未正确打开,但是未显示该部分代码。 另外,您显示factory的关闭,但该变量不与显示的代码段有关。

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

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

因此,实现循环的正确方法是在具有该循环的类中的某个位置初始化EntityManager ,将其用于循环,然后在循环结束后将其关闭,但将EntityManagerFactory保留为其自身的逻辑流程。

另外,您不要使用Hibernate或任何JPA解决方案“填充表”。 Hibernate / JPA用于对象模型,而不用于表模型。 将您的实体类型写为对象类型(没有人工的“ ID”键字段!)。 让JPA处理映射,而不是由您的代码来处理。 考虑对象而不是表。

使用JDBC进行批量操作通常比使用JPA更好。 JPA用于建模实体,而不用于管理数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM