【问题标题】:Spring JPA : OneToMany List update results in duplicate entriesSpring JPA:OneToMany List 更新导致重复条目
【发布时间】:2019-04-17 01:58:01
【问题描述】:

我有以下 JPA 表。我使用了单向 OneToMany 关系。

@Entity
@Table(name = "xxx")
public class Parent {
   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "Child_ID")
   private Set<Child1> child;

   //getter setters

}

@Entity
@Table(name = "xxx")
public class Child {
   //other colmns

   //getter setters

}

当我第一次将条目添加到上面的父集(比如 20)和 save() 时,它会成功保存到数据库。 然后在同一组中,我又添加了 10 个并调用了保存方法。它为db节省了10个新的。如果我再次调用 save 它添加相同的 10 到数据库再次创建重复条目。

Parentrepository.save(parentObject);

【问题讨论】:

  • 您能说明一下您是如何调用值的设置和保存的吗?
  • @arjayosma :已编辑问题。我正在使用存储库保存父对象。因为它有 cascadeType All 它也可以保存孩子。
  • 你是如何在这里填充你的 parentObject 变量的。您一定是在没有更新 ID 的情况下多次保存同一个对象。
  • @arjayosma :我只是多次保存同一个对象。对于某些孩子,它会更新现有的行,但对于 OneToMany(set) 对象,它会一次又一次地插入。
  • 您是否使用保存返回的对象进行进一步设置?

标签: java spring jpa spring-data-jpa


【解决方案1】:

只需在子实体中生成有效的主键,即

@Id
@Column(name = "child_name")
private String name;

并覆盖@Equals 和@HashCode 方法:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Child )) return false;
    return name != null && name.equals(((Child) o).name);
}
@Override
public int hashCode() {
    return Objects.hashCode(this);
}

【讨论】:

  • 我在子表中有主键。它将行保存到数据库,但是当我调试对象主键为空时。
  • @RohanLopes 这是因为一旦您将数据持久保存在数据库中,就会自动创建密钥,但是在您自己的本地执行中,保存数据的对象将不会获得已保存的 ID从数据库中保存。
  • 保存后更新其他 20 个对象。它的顺序是子主键中的值更新。但是对于那些在 Set 中新添加的孩子,它没有。
  • @RohanLopes 你是怎么写孩子的主键的?
  • 我创建了子对象并与父对象关联。孩子的主键将由 jpa 自动创建。
【解决方案2】:

我发现了问题。 Jpa 存储库保存对象并返回更新的对象。

    <S extends T> S save(S var1);

实体对象应该是不可变的(我是这么认为的)。这意味着它会在保存操作后更新值(在本例中为序列号)。但是在保存操作之后,它没有更新同一对象中的序列号。当我使用返回的对象时,它起作用了。下面是修改后的代码。

    parentObject = Parentrepository.save(parentObject);

【讨论】:

    【解决方案3】:

    根据代码 Parent 类与 Child 类具有 一对多 映射。
    每次你打电话
    Parentrepository.save(parentObject);
    确保您已正确设置以下行

    parentObject.setChild(SetOfChildObjects);
    

    同时覆盖 Child 类中的 Equals 和 hashCode

    如果您设置不当,那么 DB 中的表将相应更新。

    注意:为了更好地分析,您可以分享实际代码吗?

    【讨论】:

      猜你喜欢
      • 2018-06-05
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      相关资源
      最近更新 更多