我在开发工作中遇到了一些令人费解的事情。
removePreviousFoodMenuItems(oldRefList);
shFood.setNewFoodMenuItems(newRefList);
em.merge(shFood);
em.flush(); //Error occurs
如果我在合并之前调用removePreviousFoodMenuItems,我将在运行时获得“无法合并已经删除的实体”异常。但是,这不应该发生,因为我已经设置了shFood来引用一组新的食物菜单项(newRefList)。那么为什么merge仍然试图合并已经删除的oldRefList元素呢?如果我在flush语句后放入removePreviousFoodMenuItems,则不会发生此问题。
shFood.setNewFoodMenuItems(newRefList);
em.merge(shFood);
em.flush(); //Error does not occur
removePreviousFoodMenuItems(oldRefList);
以下是removePreviousFoodMenuItems
的代码public void removePreviousFoodMenuItems(ArrayList<FoodMenuItem> oldRefList){
for (Object f : oldRefList) {
FoodMenuItem foodMenuItem = (FoodMenuItem) f;
foodMenuItem.setStakeholderFood(null);
foodMenuItem.setPhotoEntity(null);
em.remove(foodMenuItem);
//em.flush();
}//end for
}//end removePreviousFoodMenuItems
真的很感激对此的一些建议!
更新:如何创建newRefList:
StakeholderFood stakeholder = em.find(StakeholderFood.class, stakeholderID);
ArrayList<FoodMenuItem> newRefList = new ArrayList<FoodMenuItem>();
for (Object o : menuItem) {
FoodMenuItem fmi = (FoodMenuItem) o;
FoodMenuItem newFmi = new FoodMenuItem();
String previousName = fmi.getItemName();
newFmi.setItemName(previousName);
newFmi.setItemPrice(fmi.getItemPrice());
newFmi.setPhotoEntity(fmi.getPhotoEntity());
//Upload the photos for each item attached to menuItem
Photo photo = fmi.getPhotoEntity();
if(photo!=null){
photo.setFoodmenuItem(newFmi); //set new relationship, break off with old
em.merge(photo); //This will merge newFmi as well Fix this tomorrow
em.flush(); //update the links immediately
}
if (photo != null && fmi.getContainsImage() == Boolean.FALSE) {
uploadFoodMenuItemImages(photo);
newFmi.setPhotoEntity(photo);
newFmi.setContainsImage(Boolean.TRUE);
newFmi.setRenderedImage(Boolean.FALSE);
newFmi.setRenderedImageAltText(Boolean.FALSE);
}//end photo
else {
newFmi.setRenderedImageAltText(Boolean.TRUE);
}
newFmi.setStakeholderFood(stakeholder);
newRefList.add(newFmi);
}//end for
答案 0 :(得分:2)
FoodMenuItem
和oldRefList
都有一个或多个newRefList
的相同实例。将移除应用于oldRefList
中的所有项目会导致newRefList
中的某些实体被移除。
结果是shFood
拥有这样一个列表,其中至少删除了一个FoodMenuItem
。如果在删除之前执行flush,那么在执行flush时,就没有这样的问题,因为shFood
没有引用已删除的实例。