jpa/hibernate crud repository-update将向数据库中添加重复的子示例

unguejic  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(404)

我有2个类(一对多Map)。
父类:

@Entity
@Table(name = "parent")
public class Parent{

@Id
private int ParentId;

@OneToMany(cascade=CascadeType.ALL, mappedBy = "parent")
private List<Child> childEntities;

儿童班:

@Entity
@Table(name = "child")
public class Child{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int childId;

@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.DETACH, CascadeType.REFRESH, CascadeType.MERGE})
@JoinColumn(name="parent_id")
private Parent parent;

当我要保存父对象时,请使用parentrepository.save(parent)保存数据库,一切正常。父级和子级保存到数据库中。问题是,当我想对已经在数据库中的父表执行parentrepository.save(parent)时(jpa将执行update-它更新父表,但在子表中插入新行)。父表是正确的,但在子表中我有重复的值。child中的主键是serial(我使用postgresdb)。
假设我有一个空数据库,我有两行代码:
parentrepository.save(父级);
parentrepository.save(父级);
在这两行之后,我将在数据库的表parent中有一行,但他的每个子项都在表child中有两次。

3hvapo4f

3hvapo4f1#

考虑到你正在使用 @GeneratedValue ,调用时将生成子实体id sava 第一次。
如果您检查save方法文档,您将看到它确实返回您保存的对象的新示例。
这个新示例包含父实体和子实体,子实体的id由spring在这些子实体上生成。
您需要做的另一个重要更改是在用注解的属性中使用 Package 器类型而不是原语 @Id . Package 可以包含 null 值,这对于spring了解实体是新实体还是要更新的实体很重要。查看spring数据jpa文档了解更多信息。
代码的问题首先是您使用的是带注解的基元类型属性 @Id (将其更改为 Package 器类型)第二个是您应该使用 save 进一步操作的方法。

相关问题