java.lang.IllegalStateException:在同步期间,通过未标记为级联的关系找到新对象PERSIST

时间:2016-01-06 09:35:44

标签: jpa many-to-many cascade illegalstateexception persist

我有两个关于多对多的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

有没有办法自动在表格中创建的成分对象?

我尝试添加CascadeType.PERSIST但它也没有工作

@ManyToMany(mappedBy = "ingredients", cascade = CascadeType.PERSIST) 
private List<Recipie> recipies; 

2 个答案:

答案 0 :(得分:3)

首先,对于双向关系,双方都需要更新,所以:

recipe.getIngredients().add(ingredient);
ingredient.getRecipes().add(recipe);

然后,您可以在要传递给PERSIST的关系一侧将级联设置为save()。因此,如果您要保存recipe,则应使用

标记Recipe.ingredients
@ManyToMany(cascade = CascadeType.PERSIST)

(旁注,拼写为“食谱”,而不是“收件人 e”)

答案 1 :(得分:1)

正如@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);

然后应该级联持久/正确更新。

当你试图找出如何将数量与成分相关联时,真正的乐趣就会开始......