2012-07-19 54 views
2

我在開發工作中遇到了一些令人費解的事情。無法合併已刪除的實體

removePreviousFoodMenuItems(oldRefList); 
shFood.setNewFoodMenuItems(newRefList); 
em.merge(shFood); 
em.flush(); //Error occurs 

如果我合併之前調用removePreviousFoodMenuItems,我會在運行時「無法合併已經被刪除的實體」異常。但是,這不應該發生,因爲我已經設置shFood引用一組新的食物菜單項(newRefList)。那麼爲什麼合併仍然試圖合併已經被刪除的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 

真的會在此欣賞一些意見的代碼!

UPDATE:如何創建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 

回答

2

你必須在這兩個oldRefListnewRefListFoodMenuItem一個或多個相同的實例。將刪除應用於oldRefList中的所有項目,然後導致newRefList中的一些實體被刪除。

後果是shFood擁有這樣一個列表,其中至少有一個FoodMenuItem被刪除。如果在移除之前執行刷新,那麼在刷新發生的時刻,不會有這樣的問題,因爲shFood不會引用已移除的實例。

+0

嗯,但不應該發生。因爲我爲oldRefList中的每個實例創建了一個新實例。我已更新我的代碼以顯示如何創建我的newRefList。期待您的迴音! – 2012-07-19 05:41:15

+0

嗨,米克!謝謝!最終,我終於明白,罪魁禍首是photoEntity。舊的和新的foodmenuitems(newFmi和fmi)都指向相同的photoEntity。因爲FoodMenuItem有一個帶有photoEntity的級聯類型ALL,所以刪除舊的foodmenuitem(fmi)也會刪除photoEntity。既然fmi和newfmi都引用了相同的photoEntity,這會產生與剛纔描述的相同的問題。 – 2012-07-19 05:58:55