【问题标题】:JPA repository table is not saving new id's but overriding or modifingJPA 存储库表不保存新 ID,而是覆盖或修改
【发布时间】:2020-04-02 09:48:16
【问题描述】:

我有A.class

@Entity
@Data
public class A {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    Integer id;

    String someStringInAclass;

    @OneToMany(cascade = CascadeType.ALL)
    List<SomeObject> someObjectsList;
}

我有 SomeObject.class

@Entity
@Data
public class SomeObject {

    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    Integer id;
    String someString;
    Integer someInteger;
}

我在数据库中保存了一个对象:

SomeRepository.save(A);

表格看起来像这样:

然后我在 B 对象中使用不同的值再次保存 A 对象:

SomeRepository.save(A);

那么表格如下所示:

表 B 已正确扩展,但表 A_B 只是覆盖了 B_id 而不是将新的 B_id 放入 4 行。

然后,当我从数据库中检索对象 A 时,我只从 B 对象中获取最后 4 个值。

如何在不覆盖的情况下保存新值(向 A_B 添加新行)?

编辑:

我将 A_id 作为外键添加到 B 表中。再次 - 第一次保存正确存储:

然后在使用 B 的不同值进行第二次保存后,它会修改 A_id 列的值以插入第一个可插入的 4 个值(为空)。所以表格看起来像这样:

【问题讨论】:

  • 为什么要为 oneToMany 关系使用不同的表?
  • @a_horse_with_no_name 我使用 JPA。
  • @Tarun 我不明白你的意思。有没有其他方法可以做到这一点?
  • 我的意思是,如果这是一对多关系,您可以将 B 表中 A 的 id 保存为外键,而不是使用不同的表 A_B。
  • @Tarun 我将 A_id 添加为 B 表的外键。第一次保存正确存储,但第二次保存我获得:A_id 列的空值?

标签: java postgresql jpa


【解决方案1】:

由于对象已经保存并具有分配的 id,JPA 假定您指的是数据库中的相同条目。您需要克隆对象:

@Entity
@Data
public class A {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    Integer id;

    String someStringInAclass;

    @OneToMany(cascade = CascadeType.ALL)
    List<SomeObject> someObjectsList;

    public A(A source) {
        this.someStringInAclass = source.someStringInAClass;
        this.someObjectsList = new ArrayList<SomeObject>();

        for (SomeObject o : source.someObjectsList) {
            this.someObjectsList.add(new SomeObject(o));
        }
    }
}

如下使用:

SomeRepository.save(a);
A aClone = new A(a);
SomeRepository.save(aClone);

【讨论】:

  • 我不是 100% 确定,但这会用新对象扩展 A 表吗?
  • 没有。它只是一个复制构造函数。由于该类已在 JPA 实现中“注册”,因此您需要一个新实例。我扩展了示例以包括 SomeObject-Instances 的克隆。
【解决方案2】:

Hibernate 处理单向关系的效率非常低,请尝试使用双向关系。

关于上述问题,这里不需要第三张表,可以通过添加@JoinColumn 来避免创建第三张表,如下所示:

     @OneToMany(cascade = CascadeType.ALL)   
     @JoinColumn(name = "fk_a_id")
     List<SomeObject> someObjectsList;

这将在 SOME_OBJECT 表中添加列“fk_a_id”。

【讨论】:

  • 我添加了:@JoinColumn 的 (nullable = false) 参数问题已解决。不需要姓名。
  • 是的,需要约束。
【解决方案3】:

我加了:(nullable = false)参数为@JoinColumn问题解决了。

所以在列表上方现在有:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(nullable = false)
List<SomeObject> someObjectsList;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2016-06-19
    • 1970-01-01
    • 2011-12-29
    • 2019-03-12
    • 1970-01-01
    相关资源
    最近更新 更多