hibernate 如何使用hibEntityManager更新包含ID的分离实体?

gab6jxml  于 2023-03-03  发布在  其他
关注(0)|答案(1)|浏览(201)

我正在用Quarkus和Hibernate开发一个REST API。现在我必须创建一个端点,它接受PUT请求来更新一个现有的实体。该请求包含整个实体,以及它在数据库中的对应ID。
资源终结点:

@PUT
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Settings update(@Valid Settings settings) {
    return settingRepository.update(settings);
}

存储库类方法:

@Transactional
public Settings update(Settings settings) {
    // This is just for test purposes, other methods like
    // entityManager.merge() did not work although it has the PK, bc it is not "attached"
    // If i pass the object to merge() without the PK, a new PK is generated.
    entityManager.unwrap(Session.class).update(settings);
    return settings;
}

因此,端点将收到数据库Map实体的解析POJO。问题是,此实体对象未“附加”,并且似乎mergeEntityManagerpersist函数都没有做我需要的事情。我需要传递对象,并根据当前主键更新它。
我试着查看了hib的Session类,因为它包含了更多的实用函数,如updatesaveOrUpdate等,但这些函数会导致错误,如主键的唯一约束psql异常-这让我认为它是在尝试执行INSERT而不是更新。

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "settings_pkey"
  Detail: Key (id)=(1) already exists.

当然,我可以简单地创建一个手动DQL查询并将所有成员作为参数传递,但从开发人员的Angular 来看,这似乎效率很低。必须有一个简单直接的方法来完成这个看似常见的任务??在EntityManager中没有方法只使实体“托管/附加”而没有任何副作用,所以它不会导致合并问题。我也不想首先必须通过PK从DB中选择实体,然后更改它,然后将更改保存回来。看起来像是一个不必要的往返。

68bkxrlz

68bkxrlz1#

这就是Hibernate的工作原理。在您的情况下,您需要首先使用EntityManager.find()从数据库中读取实体(通过id)。然后将除id之外的所有属性替换为请求中的属性。然后使用EntityManager.merge()将修改后的实体存储到数据库中。
只是一个提示:有了Spring框架,使用CrudRepository会容易得多。

相关问题