我有两个2类,它们是多对多的关系。
@Entity
@Table(name = "recipies")
public class Recipie implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String url;
private String image;
@ManyToMany
@JoinTable(
name = "recipie_ingredients",
joinColumns = {
@JoinColumn(name = "recipie_id", referencedColumnName = "id")},
inverseJoinColumns = {
@JoinColumn(name = "ingredient_id", referencedColumnName = "id")})
private List<Ingredient> ingredients = new ArrayList<>();
@Entity
@Table(name = "ingredients")
public class Ingredient implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(mappedBy = "ingredients")
private List<Recipie> recipies;
我想用这种方式创建一个新的接收器:
List<Ingredient> ingredientsList = new ArrayList<>();
String ingredientName = "example";
Ingredient ingredient = ingredientsDao.findIngredientByName(ingredientName);
if (ingredient == null) {
ingredient = new Ingredient();
ingredient.setName(ingredientName);
}
ingredientsList.add(ingredient);
.....
recipie.setIngredients(ingredientsList);
recipiesDao.addRecipie(recipie);
如果数据库中不存在成分,就会出现类似的错误
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST
有没有任何方法可以自动在表中创建Ingredient对象?
我尝试添加CascadeType.PERSIST,但它也不起的作用
@ManyToMany(mappedBy = "ingredients", cascade = CascadeType.PERSIST)
private List<Recipie> recipies;
首先,对于双向关系,双方都需要更新,所以:
recipe.getIngredients().add(ingredient);
ingredient.getRecipes().add(recipe);
然后,您可以在传递给save()
的关系一侧将级联设置为PERSIST
。因此,如果您正在保存recipe
,则应使用标记Recipe.ingredients
@ManyToMany(cascade = CascadeType.PERSIST)
(旁注,拼写为"recipie")
正如@Gimby所提到的,您需要分配关系的双方。
与@Many打交道时。。。侧面关系我总是初始化集合(你已经在一侧完成了):
@Entity
@Table(name = "recipies")
public class Recipie implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String url;
private String image;
@ManyToMany
@JoinTable(
name = "recipie_ingredients",
joinColumns = {
@JoinColumn(name = "recipie_id", referencedColumnName = "id")},
inverseJoinColumns = {
@JoinColumn(name = "ingredient_id", referencedColumnName = "id")})
private List<Ingredient> ingredients = new ArrayList<>();
...
}
@Entity
@Table(name = "ingredients")
public class Ingredient implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(mappedBy = "ingredients")
private List<Recipie> recipies = new ArrayList<>();
...
}
然后你的逻辑略有变化:
String ingredientName = "example";
Ingredient ingredient = ingredientsDao.findIngredientByName(ingredientName);
if (ingredient == null) {
ingredient = new Ingredient();
ingredient.setName(ingredientName);
}
...
// Don't forget to assign both sides of the relationship
recipe.getIngredients().add(ingredient);
ingredient.getRecipies().add(recipe);
recipiesDao.addRecipe(recipe);
然后,这应该会正确地级联持久化/更新。
当你试图找出如何将数量与成分联系起来时,真正的乐趣就会开始。。。