使用@ManyToOne 如何将我的一个用户映射到汽车?
Using @ManyToOne how to map my one User to Cars?
我正在尝试在用户添加优惠时将所有者(用户)映射到优惠(汽车)。使用如下设置 user_id 始终为空。我错过了什么?我认为这与控制器有关。映射对我来说似乎没问题,但我可能错了。
Owner是登录并添加offer的人,所以应该由他的id映射。
编辑
我发现我的@AuthenticationPrincipal Authentication auth 始终为 null,即使只有经过身份验证的用户才能访问 POST /api/cars 端点。这似乎违反直觉
车载控制器
@Controller
public class CarController {
@Autowired
private CarService carService;
@Autowired
UserRepository userRepository;
@GetMapping("/api/cars")
public String getCars(Model model) {
model.addAttribute("cars", carService.getAllCars());
return "cars";
}
@GetMapping("/api/cars/new")
public String createNewCarOfferForm(Model model) {
Car car = new Car();
model.addAttribute("car", car);
return "createNewOfferForm";
}
@PostMapping("/api/cars")
public String saveCar(@ModelAttribute("car") Car car, @AuthenticationPrincipal Authentication auth) {
User customUser = (User)auth;
car.setOwner(customUser);
carService.saveCar(car);
return "redirect:/api/cars";
}
@GetMapping("/api/cars/view/{id}")
public String viewOffer(@PathVariable Long id, Model model) {
model.addAttribute("car", carService.getCarById(id));
return "viewOffer";
}
}
用户实体
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String roles = "ROLE_USER";
@OneToMany(mappedBy = "owner")
private Set<Car> cars = new HashSet<>();
public User() {
super();
}
public User(String username, String password, String roles) {
super();
this.username = username;
this.password = password;
this.roles = roles;
//GETTERS SETTERS
汽车实体
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String carPhotoUrl;
private String carTitle;
private double price;
private int yearModel;
private int mileage;
private String engineType;
private float engineCapacity;
private int enginePower;
private String gearboxType;
private String driveType;
private String colour;
private Boolean isDamaged;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="user_id", referencedColumnName = "id")
private User owner;
public Car() {
super();
}
public Car(String carPhotoUrl, String carTitle, double price, int yearModel, int mileage, String engineType,
float engineCapacity, int enginePower, String gearboxType, String driveType, String colour,
Boolean isDamaged) {
super();
this.carPhotoUrl = carPhotoUrl;
this.carTitle = carTitle;
this.price = price;
this.yearModel = yearModel;
this.mileage = mileage;
this.engineType = engineType;
this.engineCapacity = engineCapacity;
this.enginePower = enginePower;
this.gearboxType = gearboxType;
this.driveType = driveType;
this.colour = colour;
this.isDamaged = isDamaged;
}
//GETTERS SETTERS
用户存储库
public interface UserRepository extends JpaRepository<User, Long>
{
Optional<User> findByUsername(String username);
Optional<User> findById(Long id);
}
用户详情服务
public class UserDetailsService implements UserDetails{
private String username;
private String password;
private List<GrantedAuthority> authorities;
public UserDetailsService() {
super();
}
public UserDetailsService(User user){
this.username=user.getUsername();
this.password=user.getPassword();
this.authorities = Arrays.stream(user.getRoles().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
我认为您需要在所有者中提及级联类型“cascade=CascadeType.ALL”,这实际上意味着用户(所有者)发生的任何更改也必须级联到汽车。
如果我们保存一个用户(所有者),那么所有关联的汽车也将被保存到数据库中。如果您删除一个用户(所有者),那么与该用户(所有者)关联的所有汽车也将被删除。足够简单!
我修好了,但花了我一些时间。
现在这是添加汽车的端点(因此没有@AuthenticationPrincipal)
@PostMapping("/api/cars/addCar")
public String saveCar(@ModelAttribute("car") Car car, Principal
principal) {
User user = userService.getUserByName(principal.getName());
car.setOwner(user);
carService.saveCar(car);
return "redirect:/api/cars";
}
我敢打赌这不是一个干净的解决方案。我已将 return 类型的 UserRepository 从可选更改为用户。我认为这将在未来带来更多问题。但目前它有效。
我正在尝试在用户添加优惠时将所有者(用户)映射到优惠(汽车)。使用如下设置 user_id 始终为空。我错过了什么?我认为这与控制器有关。映射对我来说似乎没问题,但我可能错了。 Owner是登录并添加offer的人,所以应该由他的id映射。
编辑 我发现我的@AuthenticationPrincipal Authentication auth 始终为 null,即使只有经过身份验证的用户才能访问 POST /api/cars 端点。这似乎违反直觉
车载控制器
@Controller
public class CarController {
@Autowired
private CarService carService;
@Autowired
UserRepository userRepository;
@GetMapping("/api/cars")
public String getCars(Model model) {
model.addAttribute("cars", carService.getAllCars());
return "cars";
}
@GetMapping("/api/cars/new")
public String createNewCarOfferForm(Model model) {
Car car = new Car();
model.addAttribute("car", car);
return "createNewOfferForm";
}
@PostMapping("/api/cars")
public String saveCar(@ModelAttribute("car") Car car, @AuthenticationPrincipal Authentication auth) {
User customUser = (User)auth;
car.setOwner(customUser);
carService.saveCar(car);
return "redirect:/api/cars";
}
@GetMapping("/api/cars/view/{id}")
public String viewOffer(@PathVariable Long id, Model model) {
model.addAttribute("car", carService.getCarById(id));
return "viewOffer";
}
}
用户实体
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String roles = "ROLE_USER";
@OneToMany(mappedBy = "owner")
private Set<Car> cars = new HashSet<>();
public User() {
super();
}
public User(String username, String password, String roles) {
super();
this.username = username;
this.password = password;
this.roles = roles;
//GETTERS SETTERS
汽车实体
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String carPhotoUrl;
private String carTitle;
private double price;
private int yearModel;
private int mileage;
private String engineType;
private float engineCapacity;
private int enginePower;
private String gearboxType;
private String driveType;
private String colour;
private Boolean isDamaged;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="user_id", referencedColumnName = "id")
private User owner;
public Car() {
super();
}
public Car(String carPhotoUrl, String carTitle, double price, int yearModel, int mileage, String engineType,
float engineCapacity, int enginePower, String gearboxType, String driveType, String colour,
Boolean isDamaged) {
super();
this.carPhotoUrl = carPhotoUrl;
this.carTitle = carTitle;
this.price = price;
this.yearModel = yearModel;
this.mileage = mileage;
this.engineType = engineType;
this.engineCapacity = engineCapacity;
this.enginePower = enginePower;
this.gearboxType = gearboxType;
this.driveType = driveType;
this.colour = colour;
this.isDamaged = isDamaged;
}
//GETTERS SETTERS
用户存储库
public interface UserRepository extends JpaRepository<User, Long>
{
Optional<User> findByUsername(String username);
Optional<User> findById(Long id);
}
用户详情服务
public class UserDetailsService implements UserDetails{
private String username;
private String password;
private List<GrantedAuthority> authorities;
public UserDetailsService() {
super();
}
public UserDetailsService(User user){
this.username=user.getUsername();
this.password=user.getPassword();
this.authorities = Arrays.stream(user.getRoles().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
我认为您需要在所有者中提及级联类型“cascade=CascadeType.ALL”,这实际上意味着用户(所有者)发生的任何更改也必须级联到汽车。
如果我们保存一个用户(所有者),那么所有关联的汽车也将被保存到数据库中。如果您删除一个用户(所有者),那么与该用户(所有者)关联的所有汽车也将被删除。足够简单!
我修好了,但花了我一些时间。 现在这是添加汽车的端点(因此没有@AuthenticationPrincipal)
@PostMapping("/api/cars/addCar")
public String saveCar(@ModelAttribute("car") Car car, Principal
principal) {
User user = userService.getUserByName(principal.getName());
car.setOwner(user);
carService.saveCar(car);
return "redirect:/api/cars";
}
我敢打赌这不是一个干净的解决方案。我已将 return 类型的 UserRepository 从可选更改为用户。我认为这将在未来带来更多问题。但目前它有效。