2017-01-09 164 views
0

我有一个设备表,我试图用数据填充。该表有一个自动增量ID和一个制造商列。正确的方式来使用休眠填充数据表

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

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

然而,当我运行它,我得到这个错误

java.lang.IllegalStateException:会话/ 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(); 
      } 

谢谢。

回答

0

您不显示如何获取session值。显然你所关闭的session已关闭,或从未正确打开过,但未显示该代码的一部分。此外,您还会显示一个factory的结尾,但该变量未包含在您展示的片段中。

通常您可以长时间保持EntityManagerFactory左右,但EntityManager实例的寿命应该相当短。不要重复使用实体管理器(或Session)进行多个会话;在每一个之后杀死它并在你需要时开始一个新的。这将使得更容易推断什么是开放或关闭,并且可以防止臭名昭着的会话溢满。

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

因此,要实现你的循环正确的方法是在具有循环类的地方初始化EntityManager,使用它的循环,在循环之后关闭了一段时间,但离开EntityManagerFactory它自己的逻辑流。另外,您不用Hibernate或任何JPA解决方案“填充表格”。 Hibernate/JPA适用于对象模型,而不是表模型。把你的实体类型写成对象类型(没有人为的“ID”键字段!)。让JPA处理映射而不是你的代码。考虑对象,而不是表格。

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

+0

感谢您的快速响应。我已编辑我的帖子,以包括我的会议收购。但是由于我最初没有在代码中使用EntityManager,我可以对现有代码进行修复吗? – 000000000000000000000

1

播放周围插入和从循环的范围中除去的事情,我相信正确的顺序这个特定的实现休眠的使用会话以确保会话不会过早被关闭如下:

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

事务应该在任何事情被保存到会话之前启动。在完成交易之后,所有的保存都会完成。

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

请随时让我知道,如果有什么我失踪或可以优化。