【问题标题】:Spring Boot: Can not POST into ManyToMany RelationSpring Boot:无法发布到多对多关系
【发布时间】:2020-02-24 01:04:33
【问题描述】:

我有两个实体 MealMealplan 在 @ManyToMany 关系中。每个 Mealplan 可以有不同的 Meal,每个 Meal 可以在多个 Mealplan 中。

@Entity
public class Meal {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private BigDecimal price;
    private String type;

@ManyToMany(mappedBy = "mealsPerWeek")
private List<Mealplan> mealplan;

@Entity
public class Mealplan {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private int week;

    @ManyToMany
    private List<Meal> mealsPerWeek;

由于我添加了 ManyToMany 关系,我无法通过 @Postmapping 将 Meal 添加到 API 中。

膳食控制器

@RestController
@RequestMapping("/meal")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class MealController {

    @PostMapping
    public void addMeal(@RequestBody Meal meal) {
        mealRepository.save(meal);
    }

MealRepository 类扩展了 JPARepository。

每当我想在我的实体中发布一些内容时:

{
    "id": 10,
    "name": "Test",
    "price": 3.50,
    "type": "with Meat"
}

出现以下错误: "could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"

通过 INSERT INTO 添加照常工作。

【问题讨论】:

  • 您要做什么:编辑现有记录或添加新实体?您是否启用了 SQL 日志记录。生成的 SQL 是什么?

标签: java spring spring-boot spring-data-jpa spring-data


【解决方案1】:

根据您的实体映射,Id 字段定义为自动生成。在您的请求 Json 中,Id 作为 10 传递。您是要插入还是更新?您可以尝试以下请求 JSON 并查看插入是否有效。

{
    "name": "Test",
    "price": 3.50,
    "type": "with Meat",
    "mealplan": []

}

【讨论】:

    【解决方案2】:

    根据您的代码,由于您在实体 Meal 中使用了“mappedBy”,因此这是映射实体,因此 MealPlan 成为所有者实体,即它负责维护关联。

    您还需要创建另一个表,让我们调用 MealMapping 来存储 Meal 和 MealPlan 的映射,字段为 meal_id 和 mealplan_id。

    现在您需要在所有者实体中定义@JoinTable。

    @Entity
    public class Mealplan {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private int week;
    
    @ManyToMany
    @JoinTable(name="MealMapping", joinColumns={@JoinColumn(referencedColumnName="ID")}, 
    inverseJoinColumns={@JoinColumn(referencedColumnName="ID")})  
    private List<Meal> mealsPerWeek;
    }
    

    希望这会有所帮助。

    此外,由于您在 hibernate 中而不是在数据库表中定义了多对多关系,因此它可以通过 INSERT 查询工作。因此,仅当您尝试使用 hibernate 进行插入时,约束才适用。

    【讨论】:

    • 所有这些都是可选的。如果未指定,原始代码将生成使用默认表名和列,因此这不是这里的问题。
    • 您在“另一个表”中提到的内容已经由 @ManyToMany 关系完成。它创建表“mealplan_meals_per_week”并包含meal_ids 和mealplan_ids's。
    【解决方案3】:

    我为我解决了这个问题。我注意到,@GeneratedValue(strategy = GenerationType.AUTO) 没有将 ID 字段设置为“自动递增”。我已将其设置为 @GeneratedValue(strategy = GenerationType.IDENTITY) 并在不使用这样的 ID 的情况下插入新数据(如 @Ravi Sharma 所述):

    {
        "name": "Test",
        "price": 3.50,
        "type": "with Meat"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多