2

在我的代码中,我正在执行批量插入。例如,认为我有五行要插入,其中一个在插入时失败。然后休眠防止插入所有行。
就我而言,我想插入其他四个不包含错误的记录。这在 Hibernate 中可能吗?
以下是我的代码的简化版本。

void save() {
  Session session1 = HibernateUtil.getSessionFactory().openSession();
  Transaction transaction = session1.beginTransaction();

  for (int i = 0; i < 5; i++) {
    BatchSizeConf r = new BatchSizeConf();//This is my entity
    r.setId(i);
    r.setDispatchType("Disp");
    r.setBatchSize(500);
    Serializable z = session1.save(r);
    System.out.println(z);//prints ids
  }

  session1.flush();
  session1.clear();
  session1.getTransaction().commit();
  session1.close();
}

编辑


根据下面的答案,我更改了代码并解决了我的主要问题。现在我的代码是这样的。

void save() {
  for (int i = 0; i < 5; i++) {
    Session session1 = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = session1.beginTransaction();

    BatchSizeConf r = new BatchSizeConf();//This is my entity
    r.setId(i);
    r.setDispatchType("Disp");
    r.setBatchSize(500);

    try {
      session1.save(r);
      transaction.commit();
    } catch (HibernateException e) {
      System.out.println("Failed: " + i);
    }

    session1.flush();
    session1.clear();
    session1.close();
  }
}

我现在还有两个问题。

  1. 可以像上面那样创建多个会话对象吗?(我有超过 100000 条记录。)
  2. 我需要调用flush(),clear()close()上述方法吗?
4

3 回答 3

1

这是不可能的,事务将被任何异常标记为回滚。

为什么不将行切成块并为每个块设置单个事务?

看看这个文档transactions-demarcation-exceptions

如果 Session 抛出异常,包括任何 SQLException,立即回滚数据库事务,调用 Session.close() 并丢弃 Session 实例。Session 的某些方法不会使会话保持一致状态。Hibernate 抛出的任何异常都不能被视为可恢复的。通过在 finally 块中调用 close() 确保 Session 将被关闭。

于 2013-03-02T07:52:17.593 回答
1

你可以做这样的事情

Transaction tx = session.beginTransaction();
...
for (BatchSizeConf  b: BatchSizeConfList) {
    ...
    tx.commit();
}

参考Avaoid 交易异常

于 2013-03-02T09:00:07.947 回答
0

是的.. 我们可以做.. 看到这个代码。

public List<RecordErrorStatus> persistBatch(ArrayList<?> domainRecords) {

        List<RecordErrorStatus> fedRecordErrorStatusList = new ArrayList<RecordErrorStatus>();
        Session session = getSession();
        Transaction tx = session.beginTransaction();
        long rowCount = 0;
        boolean insertionFailed=false;
        for (Object object : domainRecords) {
            rowCount++;
            try {
                System.out.println("Inserting Record:"+rowCount+object);
                session.persist(object); // Persist the given transient instance
                if (! this.rollBackOnFail) {
                    tx.commit();
                    tx = session.beginTransaction();
                }
            } catch (Exception e) {
                e.printStackTrace();
                RecordErrorStatus feedRecordStatus = new RecordErrorStatus();
                feedRecordStatus.setRowNumber(String.valueOf(rowCount));
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                String exceptionAsString = sw.toString();
                feedRecordStatus.setErrorDescription(exceptionAsString);
                fedRecordErrorStatusList.add(feedRecordStatus);
                insertionFailed =true;
                tx.rollback(); //Rollback the current record..
                session.clear();//Clear the seesion.. If not, throws Nested Transaction not allowd...
                tx = session.beginTransaction();//Start again..
            } 
        }
        if (this.rollBackOnFail && insertionFailed && ! tx.wasRolledBack()) {
            tx.rollback();
            System.out.println("Rollback");
        } 
        return fedRecordErrorStatusList;
    }

于 2015-03-31T03:49:18.837 回答