Hibernate 多对多关系正在创建一个我不知道的新实例';我不想
我有两个实体,订单和产品,两者之间的关系是多对多的,我已经设置了关系,但当我尝试使用现有产品集创建新订单时,它会使用新ID创建新产品,而不仅仅是将它们连接到订单产品。 最后,我提供了我的测试截图。 这是我的订单实体:Hibernate 多对多关系正在创建一个我不知道的新实例';我不想,hibernate,spring-data-jpa,Hibernate,Spring Data Jpa,我有两个实体,订单和产品,两者之间的关系是多对多的,我已经设置了关系,但当我尝试使用现有产品集创建新订单时,它会使用新ID创建新产品,而不仅仅是将它们连接到订单产品。 最后,我提供了我的测试截图。 这是我的订单实体: @Entity @Table(name="Orders") public class Orders implements Serializable { @Id @Column(name="idorder") @GeneratedValue(
@Entity
@Table(name="Orders")
public class Orders implements Serializable {
@Id
@Column(name="idorder")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "orders_sequence")
@SequenceGenerator(name = "orders_sequence")
private Long idOrder;
@Column(name="idclient")
private Long idClient;
@Column(name="idmanager")
private String idManager;
@Column(name="iddeliveryman")
private String idDeliveryMan;
@Column(name="dateorders")
@JsonFormat(pattern="mm-dd-yyyy")
private Date dateOrder;
@Column(name="totalprice")
private double totalPrice;
@ManyToMany(cascade = { CascadeType.ALL } , fetch=FetchType.LAZY)
@JoinTable(
name = "orders_products",
joinColumns = { @JoinColumn(name = "idorder") },
inverseJoinColumns = { @JoinColumn(name = "idproduct") }
)
private List<Products> products_orders ;
//getters and setters
@实体
@表(name=“Orders”)
公共类Orders实现可序列化{
@身份证
@列(name=“idorder”)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“orders\u SEQUENCE”)
@SequenceGenerator(name=“orders\u sequence”)
私人长订单;
@列(name=“idclient”)
私人长idc客户端;
@列(name=“idmanager”)
私有字符串管理器;
@列(name=“iddeliveryman”)
私人字符串idDeliveryMan;
@列(name=“dateorders”)
@JsonFormat(pattern=“mm dd yyyy”)
私人日期订单;
@列(name=“totalprice”)
私人双总价;
@ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
@可接合(
name=“订单\产品”,
joinColumns={@JoinColumn(name=“idorder”)},
inverseJoinColumns={@JoinColumn(name=“idproduct”)}
)
私人列表产品和订单;
//接球手和接球手
我的产品实体:
@Entity
@Table(name="Products")
public class Products implements Serializable{
@Id
@Column(name="idproduct")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "products_sequence")
@SequenceGenerator(name = "products_sequence")
private Long idProduct;
@Column(name="labelproduct")
private String label;
@Column(name="priceproduct")
private int priceProduct;
@Column(name="descriptionproduct")
private String descriptionProduct;
@ManyToMany(mappedBy = "products" )
private List<Menu> menus;
@ManyToMany(mappedBy = "products_orders" )
private List<Orders> orders;
//getters and setters
@实体
@表(name=“产品”)
公共类产品实现可序列化{
@身份证
@列(name=“idproduct”)
@GeneratedValue(策略=GenerationType.SEQUENCE,生成器=“产品\序列”)
@SequenceGenerator(name=“产品\序列”)
私人长产品;
@列(name=“labelproduct”)
私有字符串标签;
@列(name=“priceproduct”)
私人产品;
@列(name=“descriptionproduct”)
私有字符串描述产品;
@许多(mappedBy=“产品”)
私人列表菜单;
@许多(mappedBy=“产品\订单”)
私人名单订单;
//接球手和接球手
我的订单管理员:
@RestController
public class OrdersController {
@Autowired
private OrdersRepository ordersRepository;
@Autowired
private ManagersRepository managersRepository;
@Autowired
private DeliveryManRepository deliverymanRepo;
@Autowired
private ClientsRepository clientsRepository;
@Autowired
private ProductsRepository productsRepos;
@PostMapping("orders/create/{idManager}/{idDeliveryMan}/{idClient}")
public ResponseEntity<?> createOrder(@Valid @RequestBody Orders order ,@PathVariable String idManager
,@PathVariable Long idClient, @PathVariable String idDeliveryMan){
Managers manager= managersRepository.findByEmail(idManager);
Clients client=clientsRepository.findByPhone(idClient);
DeliveryMen deliveryMan = deliverymanRepo.findByEmail(idDeliveryMan);
double price =0;
for (Products p: order.getProducts_orders()) {
price = price + p.getPriceProduct();
}
order.setIdClient(client.getPhone());
order.setIdDeliveryMan(deliveryMan.getEmail());
order.setIdManager(manager.getEmail());
order.setTotalPrice(price);
Orders newOrder = ordersRepository.save(order);
return new ResponseEntity<Orders>(newOrder,HttpStatus.CREATED);
}
}
@RestController
公共类OrdersController{
@自动连线
私人订单储蓄订单储蓄;
@自动连线
私有管理器存储库管理器存储库;
@自动连线
私人送货员仓库送货员报告;
@自动连线
私人客户储蓄性客户储蓄性;
@自动连线
私人产品替代产品;
@PostMapping(“订单/create/{idManager}/{idDeliveryMan}/{idClient}”)
public ResponseEntity createOrder(@Valid@RequestBody Orders,@PathVariable String idManager
,@PathVariable长idClient,@PathVariable字符串idDeliveryMan){
Managers-manager=managersRepository.findByEmail(idManager);
Clients client=clientsRepository.findByPhone(idClient);
deliveryMan deliveryMan=deliverymanRepo.findByEmail(idDeliveryMan);
双倍价格=0;
对于(产品p:order.getProducts\u orders()){
价格=价格+p.getPriceProduct();
}
order.setIdClient(client.getPhone());
order.setIdDeliveryMan(deliveryMan.getEmail());
order.setIdManager(manager.getEmail());
订单。设置总价(价格);
Orders newOrder=ordersepository.save(订单);
返回新的响应属性(newOrder,HttpStatus.CREATED);
}
}
您的关系不正确,您创建了与
产品的订单@manytomy
关系,这在理论上是正确的,但您需要与订单和订单产品的@OneToMany
关系
记住,订单有它的行,它们不是真正的产品,但应该由不同的实体来表示
产品是一种主数据,您只需设置一次就可以向用户推荐您的菜单。您的订单行中应该有这方面的参考信息,但直接链接到订单
会产生类似您的问题
产品应单独创建,不得在系统中下订单
因此,您必须在两者之间有一个实体,可以如下所示:
@Entity
@Table("order_products")
class OrderProduct {
@Id
Long id; //Keep the id as per your requirement or type in db
@ManyToOne(fetch=LAZY)
@JoinColumn(name = "order_id"
private Order order;
@ManyToOne(fetch=LAZY)
@JoinColumn(name = "product_id"
private Product product;
// getters and setter omitted
}
@Table(name = "orders")
class Order {
@OneToMany(
mappedBy = "order",
cascade = {CascadeType.ALL}
orphanRemoval = true
)
private Set<OrderProduct> orderProducts = new HashSet<>();
// Other fields as you have already
// Also add a method to add OrderProduct object to maintain this bidirectional mapping
public void addOrderProduct(OrderProduct product) {
orderProducts.add(product);
product.setOrder(this);
}
}
@实体
@表(“订购产品”)
类订单产品{
@身份证
Long id;//根据您的要求或在db中键入id
@manytone(fetch=LAZY)
@JoinColumn(name=“订单号”
私人秩序;
@manytone(fetch=LAZY)
@JoinColumn(name=“product\u id”
私人产品;
//省略了getter和setter
}
@表(name=“orders”)
阶级秩序{
@独身癖(
mappedBy=“订单”,
cascade={CascadeType.ALL}
孤立删除=真
)
private Set orderProducts=new HashSet();
//其他字段,如您已经完成的
//还要添加一个方法来添加OrderProduct对象以维护此双向映射
公共无效addOrderProduct(OrderProduct产品){
orderProducts.add(产品);
产品订单(本);
}
}
我认为这是您所需要的,请阅读createOrder
中的中的更多详细信息。您收到一个类型为Orders
的传入对象,该对象源自您所做的REST请求。如果您希望此新订单引用现有产品而不是新产品,您当然必须从数据库加载现有产品ase,而不是让Hibernate将(非托管)订单
对象的持久化级联到其(非托管)产品
对象列表中
近似
List<Products> products = new ArrayList<>();
for (Products p: order.getProducts_orders()) {
products.add(productsRepos.findById(p.getId()));
price = price + p.getPriceProduct();
}
order.setProducts(products);
List products=new ArrayList();
对于(产品p:order.getProducts\u orders()){
products.add(productsRepos.findById(p.getId());
价格=价格+p.getPriceProduct();
}
订单.产品(产品);
编辑:如果没有将@manytomy
关系设置为cascade={CascadeType.ALL},这一点会立即变得明显
默认情况下,因为如果您要保存一个订单
引用非托管产品的列表
,您将从Hibernate获得一个异常。它正在工作。谢谢!它正在工作。但它只在提交大量产品时才起作用!我已经有了实体,Spring正在自己处理它,我必须修复我的问题与