将持久实体保留在交易之外

时间:2020-05-22 16:31:43

标签: java spring hibernate spring-boot jpa

我有一种情况,我试图将复杂的数据导入数据库(带有子对象和列表对象的对象,其中一些用于更新,而另一些用于新插入)。现在,我正在使用的一般流程如下:

void importData(List dataToImport){
     Object persistedObject1 = getObjectFromDB(); // data that will be attached to various objects in my import
     HashMap map1 = preFillMap1();  // Fills a map with persisted objects from database to be attached to data
     HashMap map2 = emptyMap(); // start with an empty map here
     try{
         for(Object data : dataToImport){
                Object dbSavedData = importDataImpl(persistedObject1, map2, map3, data)
                map2.put(dbSavedData.getChild().getRecordID(), dbSavedData.getChild())
         }
     }catch(Exception e){
           logger.error("Error in transaction", e);
     }
}

@org.springframework.transaction.annotation.Transactional
void importDataImpl(Object persistedObj, HashMap map1, HashMap map2, Object dataToImport){
      // simplified import process
      dataToImport.setForeignKeyObject1(persistedObj);
      dataToImport.setForeignKeyObject2(map1.get(dataToImport.obj2ID));
      if(map2.contains(dataToImport.getChild().getRecordID()){
            dataToImport.setForeignKeyObject3(map2.get(dataToImport.obj3ID));
      }else{
            dataToImport.setForeignKeyObject3(repo.findByID(dataToImport.getChild().getRecordID());
      }
      jpaRepo.save(dataToImport);           
}

我在上面遇到的问题是,一旦我在importDataImpl中遇到错误,就会在以下调用中遇到错误:

detached entity passed to persist: com.project.ChildObject; nested exception is org.hibernate.PersistentObjectException: 
detached entity passed to persist: com.project.ChildObject org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist:com.project.ChildObject

到目前为止,我能够解决的唯一方法是在错误时重置地图,然后重试importDataImpl调用。它第二次可以正常工作,但是保留映射的目的是减少所需的数据库调用次数。我已经看到了一些关于执行EntityManager.contains(obj)检查的建议,但是根据我的判断,这是不可靠的,也不是最优雅的解决方案,因为我仍然必须重置地图。到那时,发现错误并在那里进行处理似乎更加干净。

1 个答案:

答案 0 :(得分:0)

也许您可以尝试entity.merge()。

merge()会将陈旧状态推送到数据库,并覆盖所有中间更新

相关问题