我目前在事件和用户之间具有多对多关系。数据库中自动生成的名为event_registrations的表会跟踪关系以及哪个用户根据其ID转到哪个事件。
我想做的是有一个控制器方法,该方法将一个事件ID与一个用户ID列表一起接收,以便将给定的用户从给定的事件中删除。
这是我的模型课:
@Entity
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(mappedBy = "eventRegistrations")
private List<User> userList;
public Event() { this.userList = new ArrayList<>(); }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<User> getUserList() {
return userList;
}
public void registerUser(User user){
this.userList.add(user);
}
public void removeUserRegistration(long userId){
this.userList.removeIf(user -> user.getId() == userId);
}
}
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@ManyToMany
@JsonIgnore
@JoinTable(
name = "event_registrations",
joinColumns = @JoinColumn(name="user_id", referencedColumnName =
"id"),
inverseJoinColumns = @JoinColumn(name = "event_id",
referencedColumnName = "id"))
private List<Event> eventRegistrations;
public Integer getId() {
return id;
}
public List<Event> getEventRegistrations() {
return eventRegistrations;
}
public void setEventRegistrations(List<Event> eventRegistrations) {
this.eventRegistrations = eventRegistrations;
}
}
到目前为止我在EventController中尝试过的事情:
@DeleteMapping(value = "/{id}/registrations", consumes =
{"application/json"})
public ResponseEntity deleteEventRegistrations(@RequestBody ArrayList<Long>
data, @PathVariable("id") long id){
try {
Event event = eventService.getEventById(id);
data.forEach(userId -> event.removeUserRegistration(userId));
return ResponseEntity.ok().build();
} catch(DataNotFoundException ex){
return ResponseEntity.notFound().build();
}
}
这没有问题,但是条目之后仍然存在于联接表中。进行调试时,确实会从事件对象中删除用户,但更改不会持久保存到数据库中。
感谢您的帮助!
答案 0 :(得分:1)
@Entity
public class Event {
@ManyToMany(mappedBy = "eventRegistrations")
private List<User> userList;
}
这里的mappedBy
表示User
的{{1}}列表用于维护这种多对多关系,这意味着Hibernate将更新关系表(eventRegistrations
)基于用户的event_registrations
列表的内容。您必须采用另一种方法,将其从用户的事件列表中删除:
eventRegistrations
以上代码仅用于显示想法。您可能需要对其进行抛光。
答案 1 :(得分:0)
取决于JPA的实现,您可能必须从所有权方面删除。从WebLogic + TopLink迁移到Spring Boot + Hibernate后,如果我更新了非所有权方的链接,那么多对多链接将无法正确更新。
在您的情况下,您有两个方面:用户是拥有方,而事件是非拥有方(您可以从Event的“ mappedBy”中看到这一点)。这意味着您应该从User.eventRegistrations中删除,而不是从Event.userList中删除。
无需任何其他辅助方法的快速尝试:
@DeleteMapping(value = "/{id}/registrations", consumes =
{"application/json"})
public ResponseEntity<?> deleteEventRegistrations(@RequestBody ArrayList<Long>
data, @PathVariable("id") long id){
try {
Collection<User> users = userService.findUsersByIds(data); // you need to create this
users.forEach(user -> user.getEventRegistrations().removeIf(event -> event.getId() == id));
return ResponseEntity.ok().build();
} catch(DataNotFoundException ex){
return ResponseEntity.notFound().build();
}
}