quarkus:如何用新示例更新实体?

xmq68pz9  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(370)

我正在根据领域驱动设计开发一个应用程序。因此,我获取的实体被Map到域模型。对此域模型的修改可能必须更新,因此我将域模型Map回实体(新示例)并尝试将其持久化。这是hibernate用persistentobjectexception打我手腕的时候:
分离实体传递到持久化
我试图在一个spring启动应用程序中重新创建这个问题,但是由于某种原因spring将新的实体示例连接到附加的示例(或者看起来是这样。)
总结:实体(附加)->模型->实体(分离)
这里我有一个简单的示例项目,它面临着同样的问题:
https://gitlab.com/rmvanderspek/quarkus-multithreading/-/tree/persistence
更新:以下是“诀窍”,但这是一个解决办法,感觉可能有副作用,我没有讨价还价:

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

0pizxfdo1#

问题是当一个实体有一个生成的id,但是您在通过构造函数创建的新示例上设置了一个值。这些实体必须使用 merge 用于将更改应用于持久状态。另一种方法是使用 entityManager.find() 首先检索托管实体并对该对象应用更改。
我认为这是blaze持久性实体视图的完美用例。
我创建了这个库,以便在jpa模型和自定义接口或抽象类定义的模型之间进行简单的Map,比如spring数据在steroids上的投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过jpql表达式将属性(getter)Map到实体模型。
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();
    }
}

查询是将实体视图应用于查询的问题,最简单的就是按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-集成

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

相关问题