1

首先,我想说我对这个 JPA / Hibernate 还很陌生,而且 micronaut 对我来说也是新的(我在 PHP、Python、“桌面 Java”、C++ 等方面有很多经验)。

当我通过 micronaut @Body 注释传递实体时,我无法摆脱我误解概念中的某些东西的感觉,因为它们是分离的,我必须使用em.merge(entity).

请考虑以下示例(缩短以仅显示重要部分):

我的实体.java:

import javax.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Entity
@Table(name = "entities")
@Getter
@Setter
@ToString
public class Entity{
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Column
    protected String name;
}

MyController.java:

import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;

@Controller("/entities")
public class EntitiyCrudController {

    @Inject
    private final EntityManager entityManager;

    @Post("/create")
    public HttpResponse create(@Body Entity entity) {
        try {
            entity = entityManager.merge(entity);
            return HttpResponse.ok(entity);
        } catch (ConstraintViolationException exception) {
            return HttpResponse.badRequest();
        }
    }

}

请注意,样本只是一起复制的,因此可能存在一些错误,但我认为这更多是关于选择正确方法的问题。

在我的研究过程中,到目前为止我看到的所有示例都是关于不分离的持久实体。有时我看到人们使用 DTO(属性级别的实体类的精确副本,但没有 jpa / hibernate 注释)。我认为这种方法也有一些味道,因为我必须构建一个具有完全相同属性的全新类。

如果没有将 dto 的属性转移到实体(调用 dto getter,调用实体 setter),我使用 DTO 不会有什么大问题。是否有一种“干净”的方法可以做到这一点,而无需手动传输每个属性(可能是一些基于反射的库或注释处理器)。然后我可以通过 dto id 从持久性上下文中加载一个实体,然后更新我的实体字段并触发更新。

总之,我的问题是: - 直接传递实体导致实体被分离(例如,micronaut-data 包不能以这种方式进行更新) - 使用 DTO 最终会逐个复制属性,这非常冗长

那么通过 json 将对象发布到网络服务器并保存或更新它的正确方法是什么?

如果有什么不明白的,我很乐意澄清它!

4

2 回答 2

1

IMO DTO 方法是将数据从持久层传递到 UI 层的方法。尝试使用推土机实体复印机 ( https://www.baeldung.com/dozer )。这将帮助您减少从一个实体复制到另一个实体的大量样板代码。

于 2019-10-11T09:02:19.323 回答
0

您描述的方法本身没有错。但是你必须知道你在做什么,你正在将你的休息接口与你的数据库实现结合起来。根据您的要求,这可能是一个问题。例如,如果您的应用程序需要乐观并发,您将需要在您的实体中添加一个 @Version 字段,您将通过 Web 服务自动公开此信息。

通常,您希望控制公开的数据,并且通常希望分离其余 API 的 DB 实现。顺便说一句,通常您还希望拥有一个具有业务逻辑的域对象,用于验证、业务规则......

于 2019-10-11T09:20:43.640 回答