我有一种情况,我试图将复杂的数据导入数据库(带有子对象和列表对象的对象,其中一些用于更新,而另一些用于新插入)。现在,我正在使用的一般流程如下:
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)检查的建议,但是根据我的判断,这是不可靠的,也不是最优雅的解决方案,因为我仍然必须重置地图。到那时,发现错误并在那里进行处理似乎更加干净。
答案 0 :(得分:0)
也许您可以尝试entity.merge()。
merge()会将陈旧状态推送到数据库,并覆盖所有中间更新