java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST

Blackq picture Blackq · Jan 6, 2016 · Viewed 7k times · Source

I have two 2 classes in relation many to 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; 

I would like to create a new recipie this way:

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);

If ingredient doesn't exist in database, occur errors like this

Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST

Is there any way to Ingredient objects created in the table automatically?

I try add CascadeType.PERSIST but It also doesn't work

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

Answer

Adam Michalik picture Adam Michalik · Jan 6, 2016

First of all, for a bidirectional relationship, both sides need to be updated, so:

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

Then, you can set the cascade to PERSIST on the side of the relationship which you are passing to save(). So if you are saving the recipe, you should mark the Recipe.ingredients with

@ManyToMany(cascade = CascadeType.PERSIST)

(Side note, it's spelled "recipe", not "recipie")