使用spring boot的多对多关系不保存数据加入表 [英] Many to many relationship using spring boot not saving data to join table
问题描述
我在用户和收藏项的问题之间存在多对多关系,当我为用户触发我的/questionId/favourite api 时,它应该在连接表 question_favourite 下创建一个条目,该条目将映射 user_id 和 question_id (在它们自己的表中都称为id").
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).
我看到 question_favourite 表已创建,但它始终为空.我还尝试使用 put 而不是 post 认为也许这就是为什么我没有在控制台上看到插入语句的原因,但它没有多大帮助,我想我现在有点卡住了.
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.
我在这里看到了类似的问题,但作为 Spring 的初学者,我花了几个月的时间试图弄清楚为什么我无法将数据保存到我的连接表中,我想我需要一些更具体的帮助.
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.
这是我所拥有的:
@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;
}
}
这是该项目的github链接:https://github.com/francislainy/so/tree/master/backend/src/main/java/com/francislainy/so/backend
Here is the github link for the project: https://github.com/francislainy/so/tree/master/backend/src/main/java/com/francislainy/so/backend
非常感谢.
推荐答案
在您的类 QuestionCommandServiceImpl 中,您应该添加一组创建为问题收藏夹的问题实体,如下所示:
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;
}
但最好在您的情况下,您可以通过 joinColumn 在 UserEntity 中替换 @OneToMany,它的性能更好:
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;
并尝试不使用双向或与他们一起使用@JacksonBackReference
and try to unused the bidirectional or use with them the @JacksonBackReference
希望对你有帮助;)
这篇关于使用spring boot的多对多关系不保存数据加入表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!