Spring Boot票务预订系统:自动填充登录用户ID为预订外键
问题分析与解决方案
你的核心问题是没有将当前登录用户关联到新创建的Reservation对象就执行了保存操作,导致user_id字段为空。以下是分步修复方案:
1. 修复Reservation实体的setId方法错误
你的setId方法参数和赋值不匹配,会导致ID设置无效,修正如下:
public void setId(int ticket_id) { this.id = ticket_id; // 原代码是this.id = id; 这里要改为参数ticket_id }
2. 修正ReservationController的注解冲突
ReservationController同时标注了@Service和@Controller,这会导致Spring容器管理异常,去掉@Service注解:
// 去掉@Service,只保留@Controller @Controller public class ReservationController { // ... 其他代码不变 }
3. 核心:关联当前登录用户到Reservation
在saveReservation方法中,通过CustomUserDetails获取用户ID,查询对应的User实体,设置到Reservation后再保存:
@PostMapping("/make_reservation") public String saveReservation(Reservation reservation) { // 获取当前登录用户的CustomUserDetails CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 通过用户ID查询数据库中的User实体 User currentUser = userRepository.findById(userDetails.getId()).orElseThrow(() -> new RuntimeException("User not found")); // 将User关联到Reservation reservation.setUser(currentUser); // 保存Reservation reservationRepository.save(reservation); return "index"; }
注意:确保
CustomUserDetails类中包含getId()方法,能正确返回当前用户的ID。
4. 优化ReservationService(可选但推荐)
当前ReservationService没有实际业务逻辑,建议将保存逻辑移到Service层,符合MVC分层架构:
@Service @Transactional public class ReservationService { @Autowired private ReservationRepository reservationRepo; @Autowired private UserRepository userRepository; public void saveReservation(Reservation reservation, Long userId) { User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found")); reservation.setUser(user); reservationRepo.save(reservation); } }
然后在Controller中调用Service:
@PostMapping("/make_reservation") public String saveReservation(Reservation reservation) { CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); reservationService.saveReservation(reservation, userDetails.getId()); return "index"; }
额外注意事项
- 检查
@ManyToOne注解的cascade = CascadeType.ALL是否合理:如果不希望删除Reservation时连带删除User,建议改为cascade = CascadeType.PERSIST或者去掉cascade(根据业务需求调整)。 - 确保Spring Security配置正确,当前用户已成功登录,
SecurityContextHolder能获取到有效的认证信息。
内容的提问来源于stack exchange,提问作者meimei
相关产品推荐
相关产品推荐

