Reputation: 395
I'm building a Spring system which involves users and the medication they are taking. I have a database with the tables: users, drugs
I am creating a new datatype names UserMed which is composed of a composite primary key - a drug's id and a user's username (the primary keys of the tables above)
Here is the UserMed entity code:
@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;
}
}
And here is the EmbeddedID UserMedId data type:
@RequiredArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Embeddable
public class UserMedId implements Serializable {
@NonNull
public int drug_id;
@NonNull
public String username;
}
I have a route, which my frontend POST requests to. I have double checked the front end, and it is doing the POST request with a serialised UserMed type, which looks like this:
export class UserMed {
constructor(
public drug_id: number,
public username: string,
) {
}
}
But hitting the route with a userMed type in the request body, is causing this error:
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"])]
Here is the POST mapping/route that is hit
@PostMapping("/addNewUserMed")
public String addNewUser(@RequestBody UserMed userMed) {
userMedService.addNewUserMed(userMed);
return "success";
}
And here is the addNewUserMed method:
public void addNewUserMed(UserMed userMed) {
userMedRepository.save(userMed);
}
I think the issue is that since it's a composite key which is used, the UserMed which is being sent from the frontend contains field 'username' and 'drug_id', but the Spring UserMed data type has a composite key and so only has fields 'userMedId.drug_id' and 'userMedId.username'.
Can someone please advise how to make the save operation work correctly?
Thank you
Upvotes: 5
Views: 8073
Reputation: 1681
You must not use your entity for the controller, instead, you must create a DTO corresponding to your entity and use it on the controller.
So in your scenario, you must first create a UserMedDto and UserMedIdDto and use them in the controller, after getting them you must convert them into Entity and save them.
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
}
addNewUser
controller@PostMapping("/addNewUserMed")
public String addNewUser(@RequestBody UserMedDto userMedDto) {
//Convert UserMedDto to UserMedEntity then send it to addNewUserMed
userMedService.addNewUserMed(userMedEntity);
return "success";
}
These links might be useful
1- Automatically Mapping DTO to Entity on Spring Boot APIs
2- DTO to Entity and Entity to DTO Conversion
Upvotes: -1