開発の仕事をしていると、非常に不可解なことがありました。
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