【问题标题】:Best way to insert a good amount of records in hibernate在休眠中插入大量记录的最佳方法
【发布时间】:2011-06-03 00:33:29
【问题描述】:

我正在使用休眠+播放!框架在工作,是否有使用休眠插入大量记录的“最佳实践”?每个文本文件大约有 6,000 到 10,000 个,所以我不知道 Hibernate 是否会阻塞工作或引发异常。

任何建议让我知道,如果我需要解释更多,请告诉我

【问题讨论】:

    标签: java hibernate batch-processing


    【解决方案1】:

    只需打开您的会话和事务。

    在会话的保存中添加所有元素。

    然后提交事务。

    //Remember to effective handler errors
    public void saveAll(List<Object> list) throws Exception{
    Session s = HibernateUtil.openSession();
    Transaction tx = s.beginTransaction();
    for(Object obj : list)
     s.save(obj);
    tx.commit();
    s.flush();
    s.close();
    }
    

    【讨论】:

    • 请不要这样做。对于批量事务,最好避免会话缓存,否则,您将面临 OOM 异常。对于这种特定情况,存在 StatelessSession,正如 Pangea 在 Kartoch 的回答中提到的那样。
    【解决方案2】:

    来自 *Java Persistence and Hibernate" (Manning) 并遵循 Pangea 的评论,使用无状态会话(没有持久性上下文缓存):

    StatelessSession session = sessionFactory.openStatelessSession();
    Transaction tx = session.beginTransaction();
    for ( int i=0; i<100000; i++ ) {
        Item item = new Item(...);
        session.insert(item);
    }
    tx.commit();
    session.close();
    

    【讨论】:

    • 我不会使用 Session 进行批量操作。 StatelessSesssion 旨在执行这样的批量操作,因为它不维护一级缓存:将“sessionFactory.openSession()”更改为“sessionFactory.openStatelessSession()”。从这里阅读“13.3”部分docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html
    • 谢谢Pangea,我不知道这个。
    • 我不确定 session.clear() 是否需要保留在此示例中:无需从会话缓存中逐出所有对象,因为无状态会话没有缓存。我会在源代码中写这个...
    • 我应该提到新的StatelessSession class 不提供(保存、刷新、清除)。这非常简单,它将是 session.insert(item) 然后 commit 和 session.close()
    • 对我来说,Session 在使用 sessionFactory.openStatelessSession() 时应该是 StatelessSession
    【解决方案3】:

    如果您想在休眠之外进行插入,您总是可以直接获取 Connection 对象。

    Connection connection = DB.getConnection();
    

    【讨论】:

    • 你能解释一下如何解决这个问题吗?
    【解决方案4】:

    最好是使用无状态会话。考虑以下来自 (http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html) 的示例:

    StatelessSession session = sessionFactory.openStatelessSession();
    Transaction tx = session.beginTransaction();
    
    ScrollableResults customers = session.getNamedQuery("GetCustomers")
        .scroll(ScrollMode.FORWARD_ONLY);
    while ( customers.next() ) {
        Customer customer = (Customer) customers.get(0);
        customer.updateStuff(...);
        session.update(customer);
    }
    
    tx.commit();
    session.close();
    

    【讨论】:

      【解决方案5】:

      只是对 Kartoch 答案中的代码进行了一些更正。

      根据Batch Procession,“StatelessSession 接口定义的 insert()、update() 和 delete() 操作被认为是直接的数据库行级操作。它们导致立即执行 SQL INSERT,分别是 UPDATE 或 DELETE。它们对 Session 接口定义的 save()、saveOrUpdate() 和 delete() 操作有不同的语义。"

      StatelessSession 不再需要 save()、flush()、clear()。代码应该是这样的:

      StatelessSession session = sessionFactory.openStatelessSession();
      Transaction tx = session.beginTransaction();
      
      for ( int i=0; i<100000; i++ ) {
        Item item = new Item(.....);
        session.insert(item );
      }    
      
      tx.commit();
      session.close();
      

      最后,这里讨论一下普通批量插入和StatelessSession插入的区别:Using StatelessSession for Batch processing

      【讨论】:

        猜你喜欢
        • 2013-03-31
        • 2019-12-30
        • 2014-10-27
        • 2011-02-15
        • 1970-01-01
        • 1970-01-01
        • 2022-08-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多