2

開発の仕事をしていると、非常に不可解なことがありました。

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
4

1 に答える 1

2

FoodMenuItemと の両方に の同じインスタンスが 1 つ以上oldRefListありnewRefListます。のすべてのアイテムに削除を適用すると、oldRefList一部のエンティティnewRefListが削除されます。

Consequence はshFood、少なくとも 1 つFoodMenuItemが削除されたようなリストを保持します。shFood削除する前にフラッシュを実行すると、フラッシュが行われた瞬間に、削除されたインスタンスを参照しないため、このような問題はありません。

于 2012-07-19T05:17:10.813 に答える