更新休眠JPA

问题描述

在休眠JPA中,如何更新对象? 我有一个具有两个属性的项目实体。 projectid和projectname。 这里projectid是主键。现在,在我的更新方法中,我应该能够同时修改属性projectid和projectname。查询应通过以下方式看起来像。
update PROJECT set ID=\'123\',NAME=\'Intel\' where ID=\'122\'
我想将project_id分配给user_id。
project_table
-------------
project_id  project_name  
-------------------------  
LK987       LockSystem  
MK876       MockSystem      


user_project_table
---------------------  
user_id        project_id  
--------------------------  
12343       LK987  
12344       MK876  
12343       TK656  
12675       TK656  
    

解决方法

        停止思考SQL,开始思考,2ѭ。     项目p = entityManager.find(Project.class,122);     p.setId(123);     p.setName(\“ Intel \”);     entityManager.merge(p); 也就是说,更改实体的主键几乎总是错误的选择。   您为什么要更改实体的身份?您还需要更新指向它的其他表中的所有外键。似乎很痛苦,没有收获。您最好将其设置为“业务密钥”(普通属性),并使用更永久的代理密钥。 如果确实需要更改项目的ID号,则应将主键更改为自动递增的数字。该实体看起来像这样:
@Entity
public class Project
{
    @Id @GeneratedValue
    private int id;
    private int projectId;
    private String projectName;

    // getters and setters
}
因此,您想将项目与用户关联。 您可以在项目ID(字符串,例如
\"LK987\"
)作为主键的情况下执行此操作(到目前为止,我确定您应该更改了此键),也可以使用单独的自动递增
int
作为ID。由你决定;我个人的喜好是自动增量方法,因此您以后不必担心。 您想要做的是在
Project
实体和
User
实体之间建立关系。除了存储外键字段,您应该存储实体字段(用于一对一,一对多或多对一映射)或实体集合(对于一对多,多对一,或多对多映射)。如果我了解您的需求: 每个用户可以有多个项目,每个项目可以有多个用户(因此映射是多对多的) 用户了解项目,项目也可能了解用户(因此映射是双向的)。我假设
User
是关系的所有者,
Project
是逆关系。 这意味着您将使用ѭ10注释,并指定ѭ11以及要使用的ѭ12。 用户实体类
@Entity
public class User
{
    @Id @GeneratedValue
    int id;  // the PK for user entities

    @ManyToMany
    @JoinTable(
        name=\"user_project_table\",joinColumns=@JoinColumn(name=\"user_id\"),inverseJoinColumns=@JoinColumn(name=\"project_id\"))
    Set<Project> projects;

    // snip...
}
项目实体类
@Entity
public class Project
{
    @Id @GeneratedValue
    int id;
    String projectId;
    String projectName;

    @ManyToMany(mappedBy=\"projects\")
    Set<User> users;

    // snip...
}
注意我们如何使用成熟的实体类,而不仅仅是外键。 进一步阅读《 Java EE 6教程》: 在实体字段和属性中使用集合 实体关系中的多重性 实体关系的方向     ,        如果项目ID是主键和对象的标识符,则永远不要更改它。主键的更改意味着所表示的对象更改为完全不同的内容。 JPA假定主键是固定的。读取,更新和删除操作通过其ID来标识所涉及的对象。如果更改对象的ID并执行更新,则JPA要么更新一些完全不同的对象(这可能会导致异常),要么根本找不到要更新的对象。 为了强调这一点,JPA规范禁止更改主键。 Hibernate还可从任何生成的更新语句中排除主键。参见JSR-317的第28页   其主键的值唯一   标识一个   持久上下文和   EntityManager操作如所述   在第3章“实体操作”中。的   应用程序不得更改值   主键的值(这包括不更改作为主键的可变类型或复合主键的属性的值)。行为   如果发生这种情况,则为undefined(实现可能会(但不是必须)引发异常。可移植应用程序不得依赖任何此类特定行为)。 为了获得理想的结果,您应该删除旧对象并创建一个新对象。