Hibernate + Json + строковый массив - PullRequest
2 голосов
/ 02 ноября 2019

У меня есть следующие таблицы Customers, Roles, CustomerRoles. Клиенты и роли имеют длинную PK, а CustomerRoles, очевидно, выполняет сопоставления «многие ко многим». Считайте таблицу ролей фиксированной (но не жестко закодированной), определенной системой. Т.е. к столу приводят "enum". Т.е. «Admin», «User» и т. Д.

На Java у меня есть сущность Customer и RoleEntity, и я использую Hibernate / JPA для сопоставления.

Все работаеткак это сейчас, но я получаю Json, который выглядит следующим образом:

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

Я действительно хочу, чтобы он выглядел так:

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

и внутренне имел его FK'с помощью таблицы M2M с использованием идентификаторов. Обратите внимание, что поле roleid установлено в json ignore, но оно все равно оставляет его как массив объектов, а не как массив строк.

Очевидно, что строки должны быть применены к тому, что в таблице 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;
}

1 Ответ

3 голосов
/ 02 ноября 2019

Добавьте новый метод в объекте Customer

    @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к Role просто добавьте два конструктора в Role.java

    public Role() {
    }

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

Это автоматически обработает полезную нагрузку, подобную этой, и создаст две сущности роли с именами «Admin» и «Super User».

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

Однако, если вам нужно поле id роли, вам нужно вручную обработать его перед сохранением, или вы можете сохранить имя роли в качестве внешнего ключа в таблице CustomerRoles, предполагая, что имя ролей будет уникальным.

Если вам нужна более продвинутая сериализация или десериализация, вы можете написать для нее пользовательские JsonSerializer и JsonDeserializer. См. JsonComponent , если вы используете весеннюю загрузку для обслуживания вашего API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...