【问题标题】:Detached entity passed to persist when providing identifier value for GenerationType.IDENTITY as strategy to generate the identifier为 GenerationType.IDENTITY 提供标识符值作为生成标识符的策略时传递给持久化的分离实体
【发布时间】:2016-04-24 06:27:09
【问题描述】:

我有一个具有以下结构的部门表

Field       Type            Null    Key     Default     Extra
id          int(11)         NO      PRI                 auto_increment
name        varchar(45)     NO      UNI     
description varchar(100)    YES         

注意 id 是 auto_increment(auto number) 而我使用的数据库是 MySQL。

在插入期间,如果我提供 id 的值,它会使用该 id 并插入一条记录。 下面的语句插入一条 id=9 的记录。

insert into department values(9, "dept09", "department 09");

如果我不提供 id 的值,它将获取下一个值并插入一条记录。在这种情况下 id 将是 10 。 下面的语句插入一条 id=10 的记录。

insert into department(dept_name, description) values("dept10", "department 10");

我在 Java 中的 Department 类如下所示。我正在使用休眠/JPA 作为持久性提供程序 我使用 GenerationType.IDENTITY 作为策略来生成对象的标识符。

@Entity
public class Department {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String name;
    private String description;
....

}

我坚持部门如下:

// create and persist an Department
em.getTransaction().begin();
Department dept = new Department();
dept.setId(13);
dept.setName("dept13");
dept.setDescription("Department 13");
em.persist(dept);
em.getTransaction().commit();

由于我将 id 的值提供为 13,因此我希望 id=13 的记录会保留在数据库中,但 hibernate/JPA 会给出以下错误:

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.mycompany.app.Department
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1152)
    at com.mycompany.services.DepartmentService.createDepartment(DepartmentService.java:21)

为什么说新创建的部门是独立实体? 如果我注释掉“dept.setId(13)”,它工作正常,并且一个部门(DB 中的最大 id 值)+1 作为 id 值。

【问题讨论】:

    标签: java mysql hibernate jpa


    【解决方案1】:

    根据您的实体部门,您将 id 字段标记为具有生成类型身份的身份。当休眠时在插入时看到它,它会自动将 id 增加 1。如果你不想要这个,你必须删除生成自动的东西,然后你可以将 ID 设置为你需要的任何东西。以下链接为您提供了有关如何在 hibernate 中选择生成类型的更多信息

    How to choose the id generation strategy when using JPA and Hibernate

    【讨论】:

    • 如果 id 未提供或为 0,我希望 hibernate 提供 id(max id +1)。但如果提供了 id,我希望 hibernate 使用它。这正是 MySQL 的行为。
    • 我不知道这是否可能,因为我也是休眠的初学者。您能否发布一个新问题来询问这个问题。有更多经验的人可能对此有答案。
    猜你喜欢
    • 2017-04-01
    • 2018-09-22
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 2018-05-25
    • 2014-05-28
    • 2018-05-27
    • 2018-09-09
    相关资源
    最近更新 更多