java - jackson :将对象作为属性引用

标签 java spring hibernate jpa jackson

在我的 java spring 应用程序中,我正在使用 hibernate 和 jpa,并且我使用 jackson 在 DB 中填充数据。

这是用户类:

@Data
@Entity
public class User{

    @Id
    @GeneratedValue
    Long id;

    String username;
    String password;
    boolean activated;

    public User(){}
}

第二类是:

@Entity
@Data
public class Roles {

    @Id
    @GeneratedValue
    Long id;

    @OneToOne
    User user;

    String role;

    public Roles(){}


}

在 Roles 类中,我有一个 User 属性 然后我制作了一个 json 文件来存储数据:

[ {"_class" : "com.example.domains.User", "id": 1, "username": "Admin", "password": "123Admin123","activated":true}
,
  {"_class" : "com.example.domains.Roles", "id": 1,"user":1, "role": "Admin"}]

不幸的是,当我运行它提示的应用程序时:

.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.example.domains.User: no int/Int-argument constructor/factory method to deserialize from Number value (1)
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.example.domains.Roles["user"])

问题出在

{"_class" : "com.example.domains.Roles", "id": 1,"user":1, "role": "Admin"}

当我删除上述行时,应用程序运行良好。

我认为,它提示是因为它无法创建用户实例。 那么,我该如何解决?

最佳答案

帮自己一个忙,停止使用您的实体作为 DTO!

JPA 实体具有双向关系,JSON 对象没有,我也认为实体的职责与 DTO 非常不同,尽管将这些职责合并到一个 Java 类中是可能的,但根据我的经验,这是一个非常糟糕的主意。

这里有几个原因

  • DTO 层几乎总是需要更大的灵 active ,因为它通常与 UI 相关。
  • 您应避免将数据库中的主键暴露给外部,包括您自己的 UI。我们总是为每个公开的实体生成一个额外的唯一 ID (UUID),主键保留在数据库中并且仅用于连接。
  • 您经常需要同一实体的多个 View 。或多个实体的单一 View 。
  • 如果您需要将新实体添加到与现有关系的关系中,则需要在数据库中找到现有实体,因此将新旧对象作为单个 JSON 结构发布没有任何优势。您只需要现有的 uniqueId,然后是新的。

开发人员在使用 JPA 时遇到的许多问题,特别是在合并方面的问题来自于他们在 json 被反序列化后收到一个分离的实体这一事实。但是这个实体通常没有 OneToMany 关系(如果有,它是父级在 JSON 中与子级有关系,但在 JPA 中,子级对父级的引用构成了关系)。在大多数情况下,您总是需要从数据库中加载实体的现有版本,然后将更改从 DTO 复制到实体中。

自 2009 年以来,我与 JPA 进行了广泛的合作,并且我知道分离和合并的大多数极端情况,并且使用实体作为 DTO 没有问题,但是我看到了当您处理此类时发生的困惑和错误类型代码交给不熟悉 JPA 的人。 DTO 所需的几行代码(尤其是因为您已经使用了 Lombok)非常简单,并且比尝试保存一些文件并破坏关注点分离更灵活。

关于java - jackson :将对象作为属性引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41989906/

相关文章:

spring - 在 jhipster 中为用户实体添加属性

spring - 配置Spring Boot+Hibernate+PostgreSQL

spring - 如何防止 Spring MVC 中 F5 上的确认警报

mysql - 无法找到逻辑名为 : propertymasterfk in org. hibernate.mapping.Table(mastertable) 的列及其相关的超表和辅助表

java - @Autowired 没有将我的服务注入(inject)我的托管 bean 中

java - 在 for 循环中使用它之前将 str.length() 值存储在变量中是否在 Java 中有任何性能改进?

java - 使用 Display.getRotation() 进行屏幕旋转

java - 查询今天、一周内、一个月内

c# - 使用 "return"时如何在 block 外访问任何变量?

java - Hibernate:迁移到 5.2.14,NPE