繁体   English   中英

我应该在休息请求和/或响应中使用 jpa 实体吗

[英]should i use jpa entity in rest request and/or response

我有一种情况,我可以发送 JPA 实体作为休息请求和/或获取 JPA 实体作为休息响应

@RequestMapping(value = "/products", method = RequestMethod.POST)
public @ResponseBody ProductDetailsResponse createNewProduct(@RequestBody ProductDetails newProduct)
        throws Exception {

ProductDetails是一个实体

@Entity
@Table(name = "product")
public class ProductDetails {

我应该使用它,还是从实体到另一种对象进行某种转换

没有硬性规定,但将 JPA 实体用作 DTO(数据传输对象)并不被认为是一种好的做法(出于非常好的理由和非常固执的观点)。

除了 DTO 在大小方面是实体的轻量级版本之外,还有其他优势。

我意识到的一个优点是关系的更轻版本,例如对于一对多的单向关系,您的子实体也将引用您的父实体,但您可以在 DTO 中打破该链,从而避免大量 JSON 转换和无限循环相关问题。

我发现在 DTO 级别进行 JSON 到对象转换(反之亦然)比在实体级别更容易一些,因为实体代表数据库图而不是客户端业务图。

一个简单的通用实用程序类来进行转换(从 DTO 到实体,反之亦然)就足够了。 您可以使用此处所述的模型映射器 API。

我不让实体跨越服务层边界,它在控制器上的所有 DTO,我在控制器上进行转换。

您可以浏览有关此主题的 SO 上的非常有趣的问题,

我应该将实体转换为 Repository 对象内的 DTO 并将其返回到服务层吗?

DTO 与实体的转换,反之亦然

REST API - DTO 与否?

额外的样板代码是 DTO 方法的一个缺点。

从技术角度来看,使用实体作为响应是可以的。 实体必须可序列化为响应输出格式(JSON 或 XML)。

编写测试以创建完整的实体对象(所有字段设置为非空)并尝试序列化它是个好主意。 即使是单个不可序列化的字段也会导致异常。 您更愿意在测试期间而不是在发布之后发现这一点。

在简单的情况下(CRUD 应用程序),需要实体的每个字段作为响应,这是一个不错的选择。

如果您不需要实体的每个字段作为响应,您可以使用@JsonView。

如果您的响应与实体(新字段、转换)明显不同,最好为响应创建单独的 DTO 对象。 这样,您将能够分别发展 Web API (DTO) 和数据库架构(实体)。

不,不要这样做。 它与良好实践或一些花哨的模式或任何东西无关。

原因如下:

JPA 实体,如果我们说的是 Hibernate,则与 Hibernate Session 相关联。 因此,Hibernate 可以做一些意想不到的事情。 让我们来看看:

1) Flush Mode - Flush 相当于 SQL 更新,hibernate 将根据某些规则检查对象的“脏状态”,然后执行:

       entityManager.flush();

您可能不打算调用“sqlStatement.update”,但是瞧,我们走了

2)

`class EntityA{
     //  Defaults to Lazy Fetch
     @OneToMany
     private Set<EntityB> entityBees
 }

如果我们从您的控制器执行以下操作并且休眠会话已关闭,您将收到异常,例如分离的实体等:

for (EntityB b : entityA.getEntityBees) {
    //  This is a problem
    process(b);
}

重申一下,这不是因为某些花哨的 GoF 模式,而是因为它很危险。 特别是如果您不知道自己在做什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM