java - Hibernate + Json + 字符串数组

标签 java json hibernate

我有下表“客户”、“角色”、“客户角色”。客户和角色有很长的 PK,而 CustomerRoles 显然会进行多对多映射。将 Roles 表视为系统定义的固定表(但未硬编码)。 IE。表驱动的“枚举”。 IE。 “管理员”、“用户”等

在 Java 方面,我有一个 Customer 实体和一个 RoleEntity,并且我使用 Hibernate/JPA 进行映射。

现在一切正常,但我最终得到的 Json 看起来像这样:

{
    "customerId": 100000,
    "firstName": "Bob",
    "lastName": "Jenkins",
    "roles": [
      {
        "name": "Admin"
      },
      {
        "name": "Super User"
      }
    ]
  },

我真正想要的是它看起来像:

"roles": [ "Admin", "Super User" ]

并在内部使用 ids 通过 M2M 表对其进行 FK。请注意,roleid 字段设置为 jsonignore,但它仍然将其保留为对象数组而不是字符串数组。

显然,需要根据 Roles 表中的内容强制执行字符串。

有什么建议吗?

客户实体:

@ApiModelProperty(notes="Id of the customer.", required=true, value="100000")
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@JsonProperty(access=Access.READ_ONLY)
private Long customerId = 0L;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="First name of the customer.", required=true, value="John")
private String firstName;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="Last name of the customer.", required=true, value="Smith")
private String lastName;
@ManyToMany(cascade={ CascadeType.PERSIST })
@JoinTable(name="CustomerRoles",
           joinColumns={ @JoinColumn(name="CustomerId") },
           inverseJoinColumns={ @JoinColumn(name="RoleId") }
)
private List<Role> roles = new ArrayList<>();

public Long getCustomerId() {
    return this.customerId;
}

public String getFirstName() {
    return this.firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return this.lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public List<Role> getRoles() {
    //return new ArrayList<Role>(this.roles);
    return this.roles;
}

角色实体:

@ApiModelProperty(notes="Id of the role.", required=true, value="1")
@Id
//@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long roleId;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="Name of the role.", required=true, value="Admin")
private String name;

@JsonIgnore
public Long getRoleId() {
    return this.roleId;
}

public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

最佳答案

在您的客户实体中添加新方法

    @JsonProperty("roles")
    public List<String> getRolesAsStrList() {
        return this.roles
            .stream()
            .map(Role::getName)
            .collect(toList());
    }

然后在角色属性上添加@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)

    //other annotations
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private List<Role> roles = new ArrayList<>();

要使 POST 自动从 String 绑定(bind)到 Role,只需在 Role.java 中添加两个构造函数

    public Role() {
    }

    public Role(String name) {
        this.name = name;
    }

这将自动处理这样的有效负载,并创建两个名为“管理员”和“ super 用户”的角色实体。

{
    "customerId": 100000,
    "firstName": "Bob",
    "lastName": "Jenkins",
    "roles": [ "Admin", "Super User"]
}

但是,如果您需要角色的 id 字段,则需要在持久化之前手动处理它,或者您可以将角色名称作为外键保留在 CustomerRoles 表中,假设角色名称是唯一的。

如果您需要更高级的序列化或反序列化,您可以编写自定义 JsonSerializerJsonDeserializer 为此。请参阅JsonComponent如果您使用 Spring Boot 来服务您的 api。

关于java - Hibernate + Json + 字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58674070/

相关文章:

java - 创建后根据条件将对象传播到子类

java - 解析多行固定宽度文件

java - 未创建审核表

java - 标识触发 DataIntegrityViolationException 的约束名称

java - 如何将实时摄像头图像与图像进行匹配

java - 为什么 LocalDate 没有实现 Comparable<LocalDate>?

Swift Playground 中没有输出的 JSONDecoder

java - 如何使用 String 类型的变量创建 JSON 文件

java - 如何在 JSONObject 中获取没有名称的 JSONArrays

java - "could not initialize a collection"+ @Lob + MSSQL