使用@ManyToMany复制实体



我有两个实体:膳食和产品。每顿饭都有几个产品,每种产品都可以存在于每顿饭中,因此关系为@ManyToMany,其中Meal是父母。

我想用产品保存Meal,但问题是DB中的产品是重复的。

如何归档一个案例,如果产品存在于数据库中,则不保存它,而只与现有的连接?

(应用程序解析来自外部API(Nutritionix(的产品,将它们收集在一起,然后单独保存产品,并将Meal作为计算数据的Parent(

我试着插入if(!productService.ifExists(food.getFoodName())) productService.save(food);进入保存功能并删除cascadeType,但当产品已经存在时,我会得到一个错误:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@JsonBackReference
@ManyToMany(mappedBy = "foodList")
private Set<Meal> meals = new HashSet<>();
@Column(unique = false, nullable = false)
private String foodName;
...}

@Entity
public class Meal {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@JsonManagedReference
@ManyToMany(cascade ={ CascadeType.PERSIST, CascadeType.MERGE})
private Set<Product> foodList = new HashSet<>();
@NaturalId
@Column(unique = true, nullable = false)
private String mealName;
...}

public Meal saveMeal(List<Food> foodList, String mealName){
Meal newMeal = new Meal();
newMeal.setMealName(mealName);
List<Product> productList = parseFoodToProduct(foodList);
productList.stream().forEach(y -> newMeal.getFoodList().add(y));
for(Product food : productList) {
newMeal.setNfCalories(newMeal.getNfCalories() + food.getNfCalories());
newMeal.setNfCholesterol(newMeal.getNfCholesterol() + food.getNfCholesterol());
newMeal.setNfDietaryFiber(newMeal.getNfDietaryFiber() + food.getNfDietaryFiber());
newMeal.setNfP(newMeal.getNfP() + food.getNfP());
newMeal.setNfPotassium(newMeal.getNfPotassium() + food.getNfPotassium());
newMeal.setNfProtein(newMeal.getNfProtein() + food.getNfProtein());
newMeal.setNfSaturatedFat(newMeal.getNfSaturatedFat() + food.getNfSaturatedFat());
newMeal.setNfSodium(newMeal.getNfSodium() + food.getNfSodium());
newMeal.setNfSugars(newMeal.getNfSugars() + food.getNfSugars());
newMeal.setNfTotalCarbohydrate(newMeal.getNfTotalCarbohydrate() + food.getNfTotalCarbohydrate());
newMeal.setNfTotalFat(newMeal.getNfTotalFat() + food.getNfTotalFat());
newMeal.setServingWeightGrams(newMeal.getServingWeightGrams() + food.getServingWeightGrams());

}
return mealService.save(newMeal);
}

首先,可以将成分称为Ingredients,而不是Products。

其次,问题可能在于我们看不到的方法parseFoodToProduct(foodList);的代码,与指令有关

@JsonManagedReference
@ManyToMany(cascade ={ CascadeType.PERSIST, CascadeType.MERGE})
private Set<Product> foodList = new HashSet<>();

如果在parseFoodToProduct(foodList);中创建新的Product(xxx = new Product(...)(,而不是从数据库中加载它们,这肯定会适得其反。

去掉CascadeType,始终单独创建/检索/更新/存储Product,这样它们就完全独立于使用/引用它们的位置。

最新更新