【问题标题】:Element with that ID already exists in the database具有该 ID 的元素已存在于数据库中
【发布时间】:2023-03-12 23:52:01
【问题描述】:

我正在从事一个练习 Spring Boot 项目,该项目从 mysql 数据库中列出/添加/更新/删除数学问题。我正在使用带有 JPA 的 Spring Boot 来执行数据库操作。就我而言,数据库已经存在问题,并且按钮“listproblems”将所有按钮返回到表中。我可以毫无问题地编辑/删除。但是当涉及到添加新问题时,我不知道如何将新条目添加到数据库中。在这一点上,我不知道要分享什么,但这里是当前的 addProblem 方法:

//This is in the ProblemController.java on the server side application

@PostMapping("/post")
    public void addProduct(@RequestParam("cont") String pcont) {

        // Get a valid pid first
        Iterable<Problem> problist = probRepository.findAll();
        int min = 100000;
        int max = 0;
        int gap = 0;

        for (Problem myprod : problist) {
            if (myprod.getPid() < min) {
                min = myprod.getPid();
            } 
            if (myprod.getPid() > max) {
                max = myprod.getPid();
            }
        }

        for (int i = min + 1; i < max; i++) {
            if (!probRepository.existsById(i)) {
                gap = i;
                break;
            }
        }

        if (gap == 0) {
            gap = max + 1;
        }

        System.out.println("max: " + max);

        max = max + 1;

        Problem prob = new Problem();
        prob.setPid(max);
        prob.setContent(pcont);
        probRepository.save(prob);
    }

Problem.java 实体类

@Entity
public class Problem {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer pid;

    @Column(name = "content")
    private String content;

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

这个函数基本上是遍历项目以找到最大索引,然后将索引增加 1 以获得下一个索引。但它仍然不起作用。

如果您想看任何特别有助于我理解这一点的内容,请告诉我。

【问题讨论】:

    标签: java mysql spring-boot maven jpa


    【解决方案1】:

    不看Problem Entity 有点难以理解ID情况。

    只是一些建议。看一下:objectdbSpring Guide 并检查有关 @Id 注释以及如何使用它的部分。另外,请记住,在不查看您的数据库的情况下,数据库已经填充了该主键是可能的。我建议您在每次运行后添加一种方法来清除数据库或在内存中使用 H2。

    【讨论】:

    • 嗨@fjsventura,感谢您的回复。我刚刚添加了问题实体。是的,我会看看那些提到的参考资料。但是,如果您在查看 Entity 类后还有其他任何内容,请告诉我。
    【解决方案2】:

    您似乎在此处明确覆盖了id prob.setPid(max);

    这意味着 spring 不会自动生成下一个 id。导致违反主/外键约束。

    【讨论】:

    • 哦!有道理,谢谢!我有一个模糊的猜测可能是问题所在,但现在我明白了。你知道我该如何解决吗?我希望在表格中添加新问题。有点像将新问题附加到现有表中。
    • 我建议删除该行并尝试它。我绝不是 spring 或 jpa 的专家。这是关于 id 生成的更好主题:stackoverflow.com/questions/1817625/…
    • 太棒了!这实际上奏效了。删除 @GeneratedValue 注释确实有效。非常感谢!
    • 嗯,这有助于添加新行。但是当我删除现有行时,新添加的问题不会进入已删除的位置。我的意思是,如果我删除 id 为 1、2、3、4、5、6 中的 3 的问题,当我添加新问题时,它会变为 7 而不是 3。这意味着新的 id 是 1, 2,4,5,6,7。我尝试寻找解决方案,但没有找到任何合适的解决方案。有什么想法吗?
    • 这是数据库排序工作的标准方式。它将使用序列中的下一个整数。例如最后 +1 。另外,我不是建议删除 @GeneratedValue 注释,而是删除 prob.setPid(max);
    【解决方案3】:

    谢谢。查看实体和您的代码,我会说您使用的是The_Auto_Strategy,它将自动生成一个ID。您可以删除:

    prob.setPid(max);
    

    您的代码应该可以工作。 如果你想设置一个 ID,你应该使用:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 2018-04-08
      • 1970-01-01
      相关资源
      最近更新 更多