SpringBoot Hibernate @ManyToOne映射问题:关联当前登录用户ID至新增商品
Hey there! Let's get that null user ID sorted out when you're adding items. The main issue here is that you aren't fetching the currently logged-in user and linking it to your new Item before saving it to the database. Let's walk through the fixes step by step:
1. Fix the Getter in Your Item Entity
First, I noticed a small typo in your Item class—your user getter method is named user() instead of the standard getUser(). This might cause issues when frameworks try to access the user field (like during form binding or serialization). Update it to:
public User getUser() { return user; }
Keep it consistent with your setUser() method.
2. Fetch the Logged-In User in Your Controller
To associate the item with the current user, you need to retrieve the authenticated user from Spring Security. Here are two common ways to do this:
Option 1: Inject Authentication Directly in the Controller Method
First, make sure you have a UserRepository (you'll need this to fetch the full User entity from the database). Inject it into your controller, then modify the itemAdd method:
@Controller public class ProductController { @Autowired private ItemRepository itemRepository; @Autowired private UserRepository userRepository; // Add this injection @GetMapping("/listItem") public String listing(Model model) { model.addAttribute("item", new Item()); return "addItem"; } @PostMapping("/process_Item") public String itemAdd(Item item, Authentication authentication) { // Get the username of the currently logged-in user String currentUsername = authentication.getName(); // Fetch the full User entity from the database (adjust the method if your User uses email instead) User currentUser = userRepository.findByUsername(currentUsername); // Link the user to the item item.setUser(currentUser); itemRepository.save(item); return "home_page"; } }
Option 2: Use SecurityContextHolder
If you prefer, you can fetch the authentication context manually:
@PostMapping("/process_Item") public String itemAdd(Item item) { // Get the authentication context Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // Extract UserDetails (contains the logged-in user's info) UserDetails userDetails = (UserDetails) auth.getPrincipal(); // Fetch the User entity User currentUser = userRepository.findByUsername(userDetails.getUsername()); item.setUser(currentUser); itemRepository.save(item); return "home_page"; }
3. Adjust the @ManyToOne Cascade Setting (Optional but Recommended)
Your Item class uses cascade = CascadeType.ALL on the @ManyToOne annotation. This means any operation on the Item (like save) will cascade to the User—which might not be what you want (e.g., you don't want to accidentally update the user when saving an item). Unless you specifically need this, change it to:
@ManyToOne @JoinColumn(name = "id") private User user;
Or if you want to cascade merge operations only:
@ManyToOne(cascade = CascadeType.MERGE) @JoinColumn(name = "id") private User user;
4. Ensure Your UserRepository Has the Right Query Method
Make sure your UserRepository interface includes a method to fetch users by username (or whatever unique identifier you use for authentication):
@Repository public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username); }
Final Notes
- Double-check your Spring Security configuration to ensure users are properly authenticated (if you haven't set this up yet, you'll need to configure a
UserDetailsServiceand security filters). - Test adding an item now—your
idcolumn in themsItemtable should no longer be null, and it will reference the logged-in user's ID.
内容的提问来源于stack exchange,提问作者James Coding

