gpt4 book ai didi

java - JPA 不抛出 EntityExistsException 但生成重复行(自动生成 PK)

转载 作者:行者123 更新时间:2023-12-01 13:06:40 26 4
gpt4 key购买 nike

我是 JPA 新手,正在进行一些实验,希望找出实体生命周期模型。我预计下面的代码会抛出 EntityExistsException。但是,它并没有抛出预期的异常,而是只是在数据库表中使用新的主键(加一)创建一个新行。

谁能解释一下这个吗?我怀疑这可能与我的 ID 字段上的 @GenerateValue 注释以及相应表中的自动增量主键有关。

下面您可以找到 3 个片段:我尝试运行的代码、我的实体定义和我的表设计。

提前感谢您澄清我的误解。

亲切的问候

ps:我使用 eclipselink 作为 jpa 实现和 Derby 数据库

脚本:

    Teacher teacher = new Teacher("John","Doe","English");

//Persist John Doe
EntityManager em = Persistence.createEntityManagerFactory("jpatest").createEntityManager();
em.getTransaction().begin();
em.persist(teacher);
em.getTransaction().commit();
em.close();

//Try to persist John Doe a second time
em = Persistence.createEntityManagerFactory("jpatest").createEntityManager();
em.getTransaction().begin();
em.persist(teacher);
em.getTransaction().commit(); //I Expect a throw here
em.close();

表格设计:

CREATE TABLE teachers (id INT GENERATED ALWAYS AS IDENTITY, firstname VARCHAR(20) ,lastname VARCHAR(40), PRIMARY KEY(id))

实体定义:

package testpackage;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="teachers", schema="USERNAME")
public class Teacher {

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

private String firstName;

private String lastName;

@Transient
private String course;




/**
* Zero argument constructor for JPA
*/
Teacher(){
}

public Teacher(String firstName, String lastName, String course){
this.firstName = firstName;
this.lastName = lastName;
this.course = course;
}




public int getId(){
return id;
}
public String getFirstName(){
return firstName;
}
public String getLastname(){
return lastName;
}
public String getCourse(){
return course;
}



public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
}

最佳答案

仅当您保留与数据库关联的同一实体时,才会抛出 EntityExistsException。

但在这里,您创建了一个具有某些值的对象,然后持久化了 2 次,并且每次持久化时自动生成唯一的主键。

因为

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

每次使用实体管理器调用 persist 方法时都会生成新的 ID。因此,就 DB 而言,两个实体都变得不同。因为DB关心主键是唯一的来区分每条记录。

所以最好这样做以获得该异常

首先从数据库获取实体并更改它,然后尝试调用保存它

EntityManager em = Persistence.createEntityManagerFactory("jpatest").createEntityManager(); 
em.getTransaction().begin();
Teacher teacher = em.find(Teacher.class,primary key)
em.persist(teacher);
em.getTransaction().commit();
em.close();

或者删除主键的自动生成并每次都手动为其分配相同的 ID。如有任何其他问题,请告诉我

关于java - JPA 不抛出 EntityExistsException 但生成重复行(自动生成 PK),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23217972/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com