我有下表“客户”、“角色”、“客户角色”。客户和角色有很长的 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
表中,假设角色名称是唯一的。
如果您需要更高级的序列化或反序列化,您可以编写自定义
JsonSerializer
和 JsonDeserializer
为此。请参阅JsonComponent如果您使用 Spring Boot 来服务您的 api。
关于java - Hibernate + Json + 字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58674070/