2012-07-19 55 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