Spring @OneToMany 问题
Spring @OneToMany problems
正在做一个有包裹服务的项目。我创建了 OrderItem API 和 Dispatcher API。现在,我想通过关系联系起来。这个想法是:dispatcher 可以有很多 orderItems。 OrderItem 只能有一个调度员。如果你删除调度员,他的订单项目也必须出去。
我已经创建了一点点,但是我在这里搞砸了,无法按逻辑完成这件事。有人会给我一些关于我应该如何解决这个问题的想法吗?
我需要把关系放在两边还是只放在其中之一?
什么时候需要创建带参数的构造函数?因为在实体 class 中你必须没有 arg 构造函数...?
订单项class:
@Entity
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank(message = "Order weight is required")
private String weight;
@NotBlank(message = "Order dimensions are required")
private String dimensions;
@NotBlank(message = "Order origin is required")
private String origin;
@NotBlank(message = "Order destination is required")
private String destination;
@NotNull(message = "Order comment cannot be null")
private String comment;
@ManyToOne
private Dispatcher dispatcher;
public OrderItem() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public String getDimensions() {
return dimensions;
}
public void setDimensions(String dimensions) {
this.dimensions = dimensions;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Dispatcher getDispatcher() {
return dispatcher;
}
public void setDispatcher(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
}
订单控制器class:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderService service;
@Autowired
private MapValidationErrorService mapValidationErrorService;
@GetMapping("/{dispatcherId}/orders")
public List<OrderItem> getAllOrderItems(@PathVariable int dispatcherId) {
return service.getAllOrderItems(dispatcherId);
}
@PostMapping("/{dispatcherId}/orders")
public ResponseEntity<?> saveOrder(@Valid @RequestBody OrderItem orderItem, @PathVariable int dispatcherId, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
orderItem.setDispatcher(new Dispatcher(dispatcherId, "", "", ""));
service.insertOrUpdate(orderItem);
return new ResponseEntity<String>("Order was created successfully", HttpStatus.CREATED);
}
@PutMapping("/update")
public ResponseEntity<?> updateOrder(@Valid @RequestBody OrderItem orderItem, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(orderItem);
return new ResponseEntity<String>("Order was updated successfully", HttpStatus.OK);
}
@GetMapping("/all")
public Iterable<OrderItem> getAllOrders() {
return service.findAllOrders();
}
@DeleteMapping("/{orderId}")
public ResponseEntity<String> deleteOrder(@PathVariable int orderId) {
if (service.findById(orderId) == null) {
throw new CustomErrorException("Order doesn't exist, check order id");
}
service.deleteOrder(orderId);
return new ResponseEntity<String>("Order with ID " + orderId + " was deleted", HttpStatus.OK);
}
@GetMapping("/{orderId}")
public ResponseEntity<OrderItem> getOrderById(@PathVariable int orderId) {
OrderItem item = service.findById(orderId);
if (service.findById(orderId) == null) {
throw new CustomErrorException("Order id not found - " + orderId);
}
return new ResponseEntity<OrderItem>(item, HttpStatus.OK);
}
}
调度员class:
@Entity
public class Dispatcher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank(message = "Dispatcher first name is required")
private String firstName;
@NotBlank(message = "Dispatcher last name is required")
private String lastName;
@NotBlank(message = "Dispatcher email name is required")
private String email;
@NotBlank(message = "Dispatcher email is required")
private String password;
@NotBlank(message = "Dispatcher phone number is required")
private String phoneNumber;
public Dispatcher() {
}
public Dispatcher(int id, String firstName, String lastName, String email) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
DispatcherControllerclass:
@RestController
@RequestMapping("/dispatcher")
public class DispatcherController {
@Autowired
DispatcherService service;
@Autowired
private MapValidationErrorService mapValidationErrorService;
@PostMapping("/save")
public ResponseEntity<?> saveDispatcher(@Valid @RequestBody Dispatcher dispatcher, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(dispatcher);
return new ResponseEntity<String>("Dispatcher was created successfully", HttpStatus.CREATED);
}
@GetMapping("/all")
public Iterable<Dispatcher> getAllDispatchers() {
return service.findAllDispatchers();
}
@GetMapping("/{dispatcherId}")
public ResponseEntity<?> getDispatcherById(@PathVariable int dispatcherId) {
Dispatcher dispatcher = service.findById(dispatcherId);
if (service.findById(dispatcherId) == null) {
throw new CustomErrorException("Dispatcher id not found - " + dispatcherId);
}
return new ResponseEntity<Dispatcher>(dispatcher, HttpStatus.OK);
}
@DeleteMapping("/{dispatcherId}")
public ResponseEntity<?> deleteDispatcher(@PathVariable int dispatcherId) {
if (service.findById(dispatcherId) == null) {
throw new CustomErrorException("Dispatcher doesn't exist, check dispatcher id");
}
service.deleteDispatcher(dispatcherId);
return new ResponseEntity<String>("Order with ID " + dispatcherId + " was deleted", HttpStatus.OK);
}
@PutMapping("/update")
public ResponseEntity<?> updateDispatcher(@Valid @RequestBody Dispatcher dispatcher, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(dispatcher);
return new ResponseEntity<String>("Dispatcher was updated successfully", HttpStatus.OK);
}
}
我认为您对关系的定义不正确。是的,你需要有无参数构造函数。这有助于休眠在从数据库
检索数据时将数据库中的值映射到 java 对象
假设您要进行单向映射,
@Entity
public class OrderItem {
@ManyToOne( cascade = CascadeType.ALL )
@JoinColumn(name = <foriegn_key_column in orderItem table i.e. id>)
private Dispatcher dispatcher;
}
@Entity
public class Dispatcher {
private List<OrderItem > orders;
}
主要区别在于双向关系使您可以双向访问。这样您就可以毫无疑问地访问另一端。它也适用于级联操作。
双向 @OneToMany
生成更好的 DML,因为 @ManyToOne
拥有关系。
单向@ManyToOne
或双向@OneToMany
比单向@OneToMany
更有效率。
在 JPA 2.0 之前,此单向 @OneToMany
使用联接 table 来管理父行和子行之间的关联。因此读取(3 tables 连接)和写入(3 tables 插入)的成本更高。
自从 JPA 2.0 用于单向 @OneToMany
您应该将其与 @JoinColumn
相关联使用
有了 @JoinColumn
@OneToMany
关联控制子 table FK.. 所以不需要额外的连接 table.
但就性能而言,没有比双向关联更好的了。
单向的优点 @OneToMany
-> 简单。
关于你的第二个问题:只有持久性框架(例如 Hibernate)才需要 NoArg。但是您可以(并且应该)使用自己的构造函数来创建 consistent
对象。
正在做一个有包裹服务的项目。我创建了 OrderItem API 和 Dispatcher API。现在,我想通过关系联系起来。这个想法是:dispatcher 可以有很多 orderItems。 OrderItem 只能有一个调度员。如果你删除调度员,他的订单项目也必须出去。 我已经创建了一点点,但是我在这里搞砸了,无法按逻辑完成这件事。有人会给我一些关于我应该如何解决这个问题的想法吗?
我需要把关系放在两边还是只放在其中之一?
什么时候需要创建带参数的构造函数?因为在实体 class 中你必须没有 arg 构造函数...?
订单项class:
@Entity
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank(message = "Order weight is required")
private String weight;
@NotBlank(message = "Order dimensions are required")
private String dimensions;
@NotBlank(message = "Order origin is required")
private String origin;
@NotBlank(message = "Order destination is required")
private String destination;
@NotNull(message = "Order comment cannot be null")
private String comment;
@ManyToOne
private Dispatcher dispatcher;
public OrderItem() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public String getDimensions() {
return dimensions;
}
public void setDimensions(String dimensions) {
this.dimensions = dimensions;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Dispatcher getDispatcher() {
return dispatcher;
}
public void setDispatcher(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
}
订单控制器class:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderService service;
@Autowired
private MapValidationErrorService mapValidationErrorService;
@GetMapping("/{dispatcherId}/orders")
public List<OrderItem> getAllOrderItems(@PathVariable int dispatcherId) {
return service.getAllOrderItems(dispatcherId);
}
@PostMapping("/{dispatcherId}/orders")
public ResponseEntity<?> saveOrder(@Valid @RequestBody OrderItem orderItem, @PathVariable int dispatcherId, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
orderItem.setDispatcher(new Dispatcher(dispatcherId, "", "", ""));
service.insertOrUpdate(orderItem);
return new ResponseEntity<String>("Order was created successfully", HttpStatus.CREATED);
}
@PutMapping("/update")
public ResponseEntity<?> updateOrder(@Valid @RequestBody OrderItem orderItem, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(orderItem);
return new ResponseEntity<String>("Order was updated successfully", HttpStatus.OK);
}
@GetMapping("/all")
public Iterable<OrderItem> getAllOrders() {
return service.findAllOrders();
}
@DeleteMapping("/{orderId}")
public ResponseEntity<String> deleteOrder(@PathVariable int orderId) {
if (service.findById(orderId) == null) {
throw new CustomErrorException("Order doesn't exist, check order id");
}
service.deleteOrder(orderId);
return new ResponseEntity<String>("Order with ID " + orderId + " was deleted", HttpStatus.OK);
}
@GetMapping("/{orderId}")
public ResponseEntity<OrderItem> getOrderById(@PathVariable int orderId) {
OrderItem item = service.findById(orderId);
if (service.findById(orderId) == null) {
throw new CustomErrorException("Order id not found - " + orderId);
}
return new ResponseEntity<OrderItem>(item, HttpStatus.OK);
}
}
调度员class:
@Entity
public class Dispatcher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank(message = "Dispatcher first name is required")
private String firstName;
@NotBlank(message = "Dispatcher last name is required")
private String lastName;
@NotBlank(message = "Dispatcher email name is required")
private String email;
@NotBlank(message = "Dispatcher email is required")
private String password;
@NotBlank(message = "Dispatcher phone number is required")
private String phoneNumber;
public Dispatcher() {
}
public Dispatcher(int id, String firstName, String lastName, String email) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
DispatcherControllerclass:
@RestController
@RequestMapping("/dispatcher")
public class DispatcherController {
@Autowired
DispatcherService service;
@Autowired
private MapValidationErrorService mapValidationErrorService;
@PostMapping("/save")
public ResponseEntity<?> saveDispatcher(@Valid @RequestBody Dispatcher dispatcher, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(dispatcher);
return new ResponseEntity<String>("Dispatcher was created successfully", HttpStatus.CREATED);
}
@GetMapping("/all")
public Iterable<Dispatcher> getAllDispatchers() {
return service.findAllDispatchers();
}
@GetMapping("/{dispatcherId}")
public ResponseEntity<?> getDispatcherById(@PathVariable int dispatcherId) {
Dispatcher dispatcher = service.findById(dispatcherId);
if (service.findById(dispatcherId) == null) {
throw new CustomErrorException("Dispatcher id not found - " + dispatcherId);
}
return new ResponseEntity<Dispatcher>(dispatcher, HttpStatus.OK);
}
@DeleteMapping("/{dispatcherId}")
public ResponseEntity<?> deleteDispatcher(@PathVariable int dispatcherId) {
if (service.findById(dispatcherId) == null) {
throw new CustomErrorException("Dispatcher doesn't exist, check dispatcher id");
}
service.deleteDispatcher(dispatcherId);
return new ResponseEntity<String>("Order with ID " + dispatcherId + " was deleted", HttpStatus.OK);
}
@PutMapping("/update")
public ResponseEntity<?> updateDispatcher(@Valid @RequestBody Dispatcher dispatcher, BindingResult result) {
ResponseEntity<?> errorMap = mapValidationErrorService.MapValidationService(result);
if (errorMap != null) {
return errorMap;
}
service.insertOrUpdate(dispatcher);
return new ResponseEntity<String>("Dispatcher was updated successfully", HttpStatus.OK);
}
}
我认为您对关系的定义不正确。是的,你需要有无参数构造函数。这有助于休眠在从数据库
检索数据时将数据库中的值映射到 java 对象假设您要进行单向映射,
@Entity
public class OrderItem {
@ManyToOne( cascade = CascadeType.ALL )
@JoinColumn(name = <foriegn_key_column in orderItem table i.e. id>)
private Dispatcher dispatcher;
}
@Entity
public class Dispatcher {
private List<OrderItem > orders;
}
主要区别在于双向关系使您可以双向访问。这样您就可以毫无疑问地访问另一端。它也适用于级联操作。
双向 @OneToMany
生成更好的 DML,因为 @ManyToOne
拥有关系。
单向@ManyToOne
或双向@OneToMany
比单向@OneToMany
更有效率。
在 JPA 2.0 之前,此单向 @OneToMany
使用联接 table 来管理父行和子行之间的关联。因此读取(3 tables 连接)和写入(3 tables 插入)的成本更高。
自从 JPA 2.0 用于单向 @OneToMany
您应该将其与 @JoinColumn
有了 @JoinColumn
@OneToMany
关联控制子 table FK.. 所以不需要额外的连接 table.
但就性能而言,没有比双向关联更好的了。
单向的优点 @OneToMany
-> 简单。
关于你的第二个问题:只有持久性框架(例如 Hibernate)才需要 NoArg。但是您可以(并且应该)使用自己的构造函数来创建 consistent
对象。