I have a many to many relationship between users and questions for favouriting items, and when I trigger my /questionId/favourite api for a user, it should create an entry under the join table question_favourite that would map out user_id and question_id (which are both called 'id' within their own table).
I see the question_favourite table has been created, but it's always empty. I tried also using a put rather than post thinking that perhaps that's why I don't see an insert statement printed on the console but it didn't help much and I think I'm a bit stuck now.
I see similar questions posted here but being a beginner on Spring and having spent literally a few months now trying to figure out why I can't save data to my join table, I thought I'd need some more specific help please.
Here is what I have:
@Entity
@Table(name = "user_profile")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userEntity", cascade = CascadeType.ALL, orphanRemoval = true)
private Collection<QuestionEntity> questionEntities;
@ManyToMany
@JoinTable(
name = "question_favourite",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "question_id", referencedColumnName = "id"))
private Set<QuestionEntity> questionFavouriteEntity;
public UserEntity(UUID id) {
this.id = id;
}
}
@Entity
@Table(name = "question")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
public class QuestionEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
@Column(name = "title", nullable = false)
private String title;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
private UserEntity userEntity;
@ManyToMany(mappedBy = "questionFavouriteEntity")
private Set<UserEntity> userEntities;
public QuestionEntity(UUID id) {
this.id = id;
}
public QuestionEntity(UUID id, String title) {
this.id = id;
this.title = title;
}
}
@PostMapping(value = "/{id}/favourite", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<QuestionFavouriteCreateDto> setFavouriteQuestion(@RequestHeader(required = false, value = "authorization") UUID userId, @RequestBody QuestionFavouriteCreateDto questionFavouriteCreateDto) {
if (userId == null) {
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
} else {
return new ResponseEntity<>(questionCommandService.favouriteQuestion(userId, questionFavouriteCreateDto), HttpStatus.OK);
}
}
@Override
public QuestionFavouriteCreateDto favouriteQuestion(UUID userId, QuestionFavouriteCreateDto qf) {
if (questionRepository.findById(qf.getQuestionId()).isPresent()) {
QuestionEntity questionEntity = questionRepository.findById(qf.getQuestionId()).get();
UserEntity userEntity = userRepository.findById(userId).get();
questionEntity.getUserEntities().add(userEntity);
userEntity.getQuestionEntities().add(questionEntity);
userRepository.save(userEntity);
questionRepository.save(questionEntity);
return new QuestionFavouriteCreateDto(questionEntity.getId(), true);
} else {
return null;
}
}
Here is the github link for the project: https://github.com/francislainy/so/tree/master/backend/src/main/java/com/francislainy/so/backend
Thank you very much.
In your class QuestionCommandServiceImpl you should add a set of the question entity created as a Question Favourite like bellow:
@Override
public QuestionFavouriteCreateDto favouriteQuestion(UUID userId, QuestionFavouriteCreateDto qf) {
if (questionRepository.findById(qf.getQuestionId()).isPresent()) {
QuestionEntity questionEntity = questionRepository.findById(qf.getQuestionId()).get();
UserEntity userEntity = userRepository.findById(userId).get();
questionEntity.getUserEntities().add(userEntity);
userEntity.getQuestionEntities().add(questionEntity);
userEntity.getQuestionFavouriteEntity().add(questionEntity); // get the Set of favorite question and add the new question
userRepository.save(userEntity);
}
return null;
}
But preferably in the your case you can remplace in UserEntity the @OneToMany by joinColumn it's more perform:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userEntity", cascade = CascadeType.ALL, orphanRemoval = true)
private Collection<QuestionEntity> questionEntities;
and try to unused the bidirectional or use with them the @JacksonBackReference
I hope that's help you;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.