Spring JPA - Как сохранить объект с помощью составного ключа (EmbeddedID) - PullRequest
1 голос
/ 01 февраля 2020

Я строю систему Spring, которая включает пользователей и лекарства, которые они принимают. У меня есть база данных с таблицами: пользователи, наркотики

Я создаю новый тип данных UserMed, который состоит из составного первичного ключа - идентификатора лекарства и имени пользователя (первичные ключи таблиц выше)

Вот код сущности UserMed:

@Entity
@Table(name = "userMeds")
public class UserMed implements Serializable {

    @Id
    @EmbeddedId
    private UserMedId userMedId;


    public UserMed(int drugID, String username) {
        this.userMedId.drug_id = drugID;
        this.userMedId.username = username;

    }

    public UserMed() {
    }


    public String getUsername() {
        return this.userMedId.username;
    }

    public void setUsername(String username) {
        this.userMedId.username = username;
    }


}

А вот тип данных EmbeddedID UserMedId:

@RequiredArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Embeddable
public class UserMedId implements Serializable {

    @NonNull
    public int drug_id;

    @NonNull
    public String username;
}

У меня есть маршрут, который запрашивает мой внешний интерфейс POST к. Я дважды проверил интерфейс, и он выполняет запрос POST с сериализованным типом UserMed, который выглядит следующим образом:

export class UserMed {
    constructor(
        public drug_id: number,
        public username: string,
    ) {
    }
}

Но попадание маршрута с типом userMed в теле запроса вызывает эта ошибка:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: N/A
 at [Source: (PushbackInputStream); line: 1, column: 28] (through reference chain: com.example.configbackendspring.entities.UserMed["username"])]

Вот отображение / маршрут POST, к которому обращаются

    @PostMapping("/addNewUserMed")
    public String addNewUser(@RequestBody UserMed userMed) {
        userMedService.addNewUserMed(userMed);
        return "success";
    }

А вот метод addNewUserMed:

   public void addNewUserMed(UserMed userMed) {
        userMedRepository.save(userMed);
    }

Я думаю, что проблема заключается в том, что поскольку используется составной ключ, UserMed, отправляемый из внешнего интерфейса, содержит поля 'username' и 'drug_id', а тип данных Spring UserMed имеет составной ключ и поэтому имеет только поля 'userMedId.drug_id 'и' userMedId.username '.

Может кто-нибудь посоветовать, как правильно выполнить операцию сохранения?

Спасибо

1 Ответ

1 голос
/ 01 февраля 2020

Вы не должны использовать свою сущность для контроллера , вместо этого вы должны создать DTO , соответствующую вашей сущности, и использовать его на контроллере.

Итак, в вашем сценарии вы должны сначала создать UserMedDto и UserMedIdDto и использовать их в контроллере, после их получения вы должны преобразовать их в Entity и сохранить их.

Создать UserMedDto

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserMedDto {

    private UserMedIdDto userMedIdDto;

    //Setters and Getters
}

Создать UserMedIdDto

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
    public class UserMedIdDto {

    @NonNull
    public int drug_id;

    @NonNull
    public String username;

    //Setters and Getters
}

Использовать Dtos в addNewUser контроллере

@PostMapping("/addNewUserMed")
    public String addNewUser(@RequestBody UserMedDto userMedDto) {
        //Convert UserMedDto to UserMedEntity then send it to addNewUserMed
        userMedService.addNewUserMed(userMedEntity);
        return "success";
    }

Эти ссылки могут быть полезны

1- Автоматическое сопоставление DTO с сущностью в API Spring Boot

2- DTO с преобразованием сущности и сущности в DTO

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