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

问题描述

我正在根据领域驱动设计开发一个应用程序。出于这个原因,我提取的实体被映射到域模型。对此域模型的修改可能需要更新,因此我将域模型映射回实体(新实例)并尝试保留它。这是 Hibernate 用 PersistentObjectException 拍我的手腕的时候:

分离实体传递给持久化

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

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

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

https://gitlab.com/rmvanderspek/quarkus-multithreading/-/tree/persistence

更新:以下是“诀窍”,但它是一种解决方法,感觉可能会有我没有讨价还价的副作用:

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

解决方法

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

我认为这是 Blaze-Persistence Entity Views 的完美用例。

我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义的模型之间轻松映射,例如类固醇上的 Spring Data Projections。这个想法是,您可以按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence Entity-Views 的 DTO/域模型可能如下所示:

@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();
    }
}

查询是将实体视图应用于查询的问题,最简单的就是通过 id 查询。

UserDto user = entityViewManager.find(entityManager,UserDto.class,id);
user.getRoles().add(entityViewManager.getReference(RoleDto.class,roleId));
entityViewManager.save(entityManager,user);

这只会刷新实际更改的数据,并避免不必要的负载。

Quarkus 和 JAX-RS 的集成使得在您的应用程序中使用它变得非常简单:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/#jaxrs-integration

    @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();
    }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...