Reputation: 405
I have Recipe
class:
@Entity
@Table(name="recipestest")
public class Recipe {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String title;
private String description;
@OneToMany(mappedBy="recipe")
private List<Ingredient> ingredients;
public Recipe(String title, String description, List<Ingredient> ingredients) {
this.title = title;
this.description = description;
this.ingredients = ingredients;
}
public Recipe() { }
/* getters and setters */
}
And Ingredient
class:
@Entity
@Table(name="ingredients")
public class Ingredient {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private int quantity;
private String unit;
@ManyToOne
@JoinColumn(name="recipe_id", nullable=false)
private Recipe recipe;
public Ingredient(String name, int quantity, String unit) {
this.name = name;
this.quantity = quantity;
this.unit = unit;
}
public Ingredient() { }
/* all getters and setters */
}
I've created two tables recipestest
and ingredients
(especially) in PostgreSQL:
CREATE TABLE ingredients (
id bigserial NOT NULL PRIMARY KEY,
name text NOT NULL,
quantity integer NOT NULL,
unit text NOT NULL,
recipe_id integer NOT NULL REFERENCES recipestest(id)
)
Both Recipe
and Ingredient
have repositories:
public interface RecipeRepository extends JpaRepository<Recipe, Long> {
}
public interface IngredientRepository extends JpaRepository<Ingredient, Long> {
}
There is this createRecipe
- method which stores an objects in the database:
@PostMapping(path = "")
public Recipe createRecipe(@RequestBody Recipe recipe) {
ingredientRepository.saveAll(recipe.getIngredients());
return recipeRepository.save(recipe);
}
I transmit this JSON via POST in Postman:
{
"title": "cake1",
"description": "description1",
"ingredients": [
{
"name": "ingredient1",
"quantity": 8,
"unit": "g"
},
{
"name": "ingredient2",
"quantity": 8,
"unit": "ml"
}
]
}
I want to recipe_id
in ingredients
table be a id
of respective recipetest
entities, but I've got such an error:
{
"timestamp": "2019-12-29T18:06:07.979+0000",
"status": 500,
"error": "Internal Server Error",
"message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}
And error in IntelliJ IDEA's terminal:
org.postgresql.util.PSQLException: ERROR: null value in column "recipe_id" violates not-null constraint
Detail: Failing row contains (47, ingredient1, 8, g, null)
My application.properties and pom.xml
Upvotes: 1
Views: 1946
Reputation: 59970
You are using :
@JoinColumn(name = "recipe_id", nullable = false)
private Recipe recipe;
Which mean that Recipe should not be null, but as we see in your JSon file, there are only the list of Ingredients
without Recipes
, which cause this problem.
There are many ways, one of them is by using CascadeType.PERSIST
, or CascadeType.ALL
based on what you want to do :
@OneToMany(mappedBy="recipe", cascade = CascadeType.PERSIST)
private List<Ingredient> ingredients;
Then in your service you can only save the recipe :
@PostMapping(path = "")
public Recipe createRecipe(@RequestBody Recipe recipe) {
//ingredientRepository.saveAll(recipe.getIngredients());
return recipeRepository.save(recipe);
}
for the id you have to use Long which accept null, not a primitive type :
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
Upvotes: 2