Hibernate 在批插入中,当一行中发生错误时,如何继续插入其他行
在我的代码中,我正在执行批插入。例如,我有五行要插入,其中一行在插入时失败。然后休眠以防止插入所有行。Hibernate 在批插入中,当一行中发生错误时,如何继续插入其他行,hibernate,batch-processing,Hibernate,Batch Processing,在我的代码中,我正在执行批插入。例如,我有五行要插入,其中一行在插入时失败。然后休眠以防止插入所有行。 在本例中,我想插入其他四条不包含错误的记录。这在Hibernate中可能吗? 以下是我的代码的简化版本 void save() { Session session1 = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = session1.beginTransaction(); fo
在本例中,我想插入其他四条不包含错误的记录。这在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(){
会话session1=HibernateUtil.getSessionFactory().openSession();
事务处理=会话1.beginTransaction();
对于(int i=0;i<5;i++){
BatchSizeConf r=new BatchSizeConf();//这是我的实体
r、 setId(i);
r、 setDispatchType(“Disp”);
r、 尺寸(500);
Serializable z=session1.save(r);
System.out.println(z);//打印ID
}
session1.flush();
会话1.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();
}
}
void save(){
对于(int i=0;i<5;i++){
会话session1=HibernateUtil.getSessionFactory().openSession();
事务处理=会话1.beginTransaction();
BatchSizeConf r=new BatchSizeConf();//这是我的实体
r、 setId(i);
r、 setDispatchType(“Disp”);
r、 尺寸(500);
试一试{
会话1.保存(r);
commit();
}捕获(休眠异常e){
System.out.println(“失败:+i”);
}
session1.flush();
会话1.clear();
session1.close();
}
}
我现在还有两个问题。flush()
、clear()
和close()
方法这是不可能的,任何异常都会将事务标记为回滚 为什么不将行切成块,并为每个块设置一个事务 看看这个文档 如果会话引发异常(包括任何SQLException),请立即回滚数据库事务,调用Session.close()并放弃会话实例。某些会话方法不会使会话保持一致状态。Hibernate引发的任何异常都不能视为可恢复的。通过在finally块中调用close()确保会话将被关闭
你可以这样做
Transaction tx = session.beginTransaction();
...
for (BatchSizeConf b: BatchSizeConfList) {
...
tx.commit();
}
请参阅是。。我们可以做。。请参阅此代码
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;
}
公共列表持久化批处理(ArrayList domainRecords){
List fedRecordErrorStatusList=新建ArrayList();
Session=getSession();
事务tx=会话.beginTransaction();
长行计数=0;
布尔插入失败=false;
for(对象:domainRecords){
行计数++;
试一试{
System.out.println(“插入记录:“+rowCount+object”);
session.persist(object);//持久化给定的临时实例
如果(!this.rollBackOnFail){
tx.commit();
tx=session.beginTransaction();
}
}捕获(例外e){
e、 printStackTrace();
RecordErrorStatus feedRecordStatus=新的RecordErrorStatus();
feedRecordStatus.setRowNumber(String.valueOf(rowCount));
StringWriter sw=新的StringWriter();
e、 printStackTrace(新PrintWriter(sw));
字符串异常AsString=sw.toString();
feedRecordStatus.setErrorDescription(字符串除外);
fedRecordErrorStatusList.add(feedRecordStatus);
insertionFailed=true;
tx.rollback();//回滚当前记录。。
session.clear();//清除session..如果没有,则抛出嵌套事务not allowd。。。
tx=session.beginTransaction();//重新启动。。
}
}
if(this.rollBackOnFail&&insertionFailed&&!tx.wasrollledback()){
tx.回滚();
System.out.println(“回滚”);
}
返回fedRecordErrorStatusList;
}
谢谢@dgregory。我修改了我的代码,请看我修改过的问题。谢谢@Suresh Atta。我修改了我的代码,请看我修改过的问题。事务提交时不需要调用会话刷新。感谢您的帮助。