Java Quarkus:如何使用新实例更新实体?

Java Quarkus:如何使用新实例更新实体?,java,hibernate,persistence,quarkus,Java,Hibernate,Persistence,Quarkus,我正在根据领域驱动设计开发一个应用程序。因此,我获取的实体映射到域模型。对此域模型的修改可能必须更新,因此我将域模型映射回实体(新实例)并尝试将其持久化。这就是Hibernate用PersistentObjectException拍打我手腕的时候: 分离的实体被传递到持久化 我试图在Spring引导应用程序中重新创建这个问题,但出于某种原因,Spring将新实体实例连接到附加实例。(或者看起来是这样。) 汇总:实体(附加)->模型->实体(分离) 这里我有一个简单的示例项目,它面临同样的问题:

我正在根据领域驱动设计开发一个应用程序。因此,我获取的实体映射到域模型。对此域模型的修改可能必须更新,因此我将域模型映射回实体(新实例)并尝试将其持久化。这就是Hibernate用PersistentObjectException拍打我手腕的时候:

分离的实体被传递到持久化

我试图在Spring引导应用程序中重新创建这个问题,但出于某种原因,Spring将新实体实例连接到附加实例。(或者看起来是这样。)

汇总:实体(附加)->模型->实体(分离)

这里我有一个简单的示例项目,它面临同样的问题:

更新:以下是“诀窍”,但这是一个解决办法,感觉可能有副作用,我没有讨价还价:

entity = respository.getEntityManager().merge(entity);
repository.persist(entity);

问题是当一个实体有一个生成的id,但您在通过构造函数创建的新实例上设置了一个值。这些实体必须使用
merge
将更改应用于持久状态。另一种方法是首先使用
entityManager.find()
检索托管实体并对该对象应用更改

我认为这是一个完美的用例

我创建了这个库,以便在JPA模型和自定义接口或抽象类定义的模型之间进行简单的映射,类似于类固醇上的Spring数据投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型

DTO/域模型在Blaze持久化实体视图中可能如下所示:

@EntityView(User.class)
@UpdatableEntityView
public interface UserDto {
    @IdMapping
    Long getId();
    String getName();
    void setName(String name);
    @UpdatableMapping
    Set<RoleDto> getRoles();

    @EntityView(Role.class)
    interface RoleDto {
        @IdMapping
        Long getId();
        String getName();
    }
}
这将只刷新实际更改的数据,并避免不必要的加载

Quarkus和JAX-RS集成使得在应用程序中使用它变得超级简单:

UserDto user = entityViewManager.find(entityManager, UserDto.class, id);
user.getRoles().add(entityViewManager.getReference(RoleDto.class, roleId));
entityViewManager.save(entityManager, user);
    @POST
    @Path("/users/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Transactional
    public Response updateUser(@EntityViewId("id") UserDto user) {
        entityViewManager.save(entityManager, user);

        return Response.ok(user.getId().toString()).build();
    }