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

2022-09-03 01:42:02

我有一个情况,我可以发送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 {

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


答案 1

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

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

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

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

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

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

关于这个主题,有一些非常有趣的问题,你可以浏览,

我是否应该将实体转换为存储库对象内的 DTO 并将其返回到服务层?

将 DTO 转换为实体,反之亦然

REST API - DTO 与否?

附加样板代码是 DTO 方法的一个缺点。


答案 2

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

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

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

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

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