Java Can';t在Springboot/Hibernate中使用OneToMany关系保存子对象
我正在Java Can';t在Springboot/Hibernate中使用OneToMany关系保存子对象,java,spring,hibernate,jpa,spring-boot,Java,Spring,Hibernate,Jpa,Spring Boot,我正在springboot中构建订单跟踪系统,使用Hibernate注释和存储库。我有一个Order类,它可以有一个OrderItems列表。这些分别映射到订单和订单项目表。下面是代表这两个方面的代码 Order.java package net.township.order; import org.hibernate.annotations.Cascade; import javax.persistence.*; import java.util.Date; import java.ut
springboot
中构建订单跟踪系统,使用Hibernate注释
和存储库
。我有一个Order
类,它可以有一个OrderItems
列表。这些分别映射到订单
和订单项目
表。下面是代表这两个方面的代码
Order.java
package net.township.order;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "orders")
public class Order {
public Order() {
}
public Order(long merchantId, String firstDeliveryName, String
lastDeliveryName, String deliveryAddress, String status, Date createDate,
Date updateDate) {
this.merchantId = merchantId;
this.lastDeliveryName = lastDeliveryName;
this.firstDeliveryName = firstDeliveryName;
this.deliveryAddress = deliveryAddress;
this.status = status;
this.createDate = createDate;
this.updateDate = updateDate;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "order_id", unique = true)
private long orderId;
@Column(name = "merchant_id")
private long merchantId;
@Column(name = "first_delivery_name")
private String firstDeliveryName;
@Column(name = "last_delivery_name")
private String lastDeliveryName;
@Column(name = "delivery_address")
private String deliveryAddress;
@Column
private String status;
@OneToMany(mappedBy = "order", cascade = {
CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE })
private List<OrderItem> orderItems;
@Column(name = "create_date")
private Date createDate;
@Column(name = "update_date")
private Date updateDate;
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getMerchantId() {
return merchantId;
}
public void setMerchantId(long merchantId) {
this.merchantId = merchantId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public String getLastDeliveryName() {
return lastDeliveryName;
}
public void setLastDeliveryName(String lastDeliveryName) {
this.lastDeliveryName = lastDeliveryName;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getFirstDeliveryName() {
return firstDeliveryName;
}
public void setFirstDeliveryName(String firstDeliveryName) {
this.firstDeliveryName = firstDeliveryName;
}
public String getDeliveryAddress() {
return deliveryAddress;
}
public void setDeliveryAddress(String deliveryAddress) {
this.deliveryAddress = deliveryAddress;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
package net.township.order;
import com.fasterxml.jackson.annotation.JsonBackReference;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
@Entity
@Table(name = "order_items")
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@Column
private String name;
@Column
private String description;
@Column
private Long quantity;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn (name="ORDER_ID")
@JsonBackReference
@Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Order order;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
}
当我从前端发布一个新的订单
时,它会正确地映射到一个订单
对象。JSON
中提供的所有OrderItems
也以列表的形式出现在对象中。但是,在我使用我的OrderRepository
的保存方法将其保存到数据库后(它只是一个crudepository
),我的数据库包含一个带有正确字段的新Order
对象,但在Order\u ITEMS
中从未创建任何内容
我已经翻阅了Hibernate
和JPAOneToMany
注释的文档,我看不出哪里出了问题。我还要补充的是,我没有手动创建模式,而是让SpringBoot为我在H2
中设置所有内容。将CascadeType.ALL
添加到映射中。将CascadeType.ALL
添加到映射中。这就是最终对我有效的方法
Order.java
package net.township.order;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "orders")
public class Order {
public Order() {
}
public Order(long merchantId, String firstDeliveryName, String lastDeliveryName, String deliveryAddress, String status, Date createDate, Date updateDate) {
this.merchantId = merchantId;
this.lastDeliveryName = lastDeliveryName;
this.firstDeliveryName = firstDeliveryName;
this.deliveryAddress = deliveryAddress;
this.status = status;
this.createDate = createDate;
this.updateDate = updateDate;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "order_id", unique = true)
private long orderId;
@Column(name = "merchant_id")
private long merchantId;
@Column(name = "first_delivery_name")
private String firstDeliveryName;
@Column(name = "last_delivery_name")
private String lastDeliveryName;
@Column(name = "delivery_address")
private String deliveryAddress;
@Column
private String status;
@OneToMany( cascade = CascadeType.ALL)
@JoinColumn(name = "order_id", referencedColumnName = "order_id")
private List<OrderItem> orderItems;
@Column(name = "create_date")
private Date createDate;
@Column(name = "update_date")
private Date updateDate;
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getMerchantId() {
return merchantId;
}
public void setMerchantId(long merchantId) {
this.merchantId = merchantId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public String getLastDeliveryName() {
return lastDeliveryName;
}
public void setLastDeliveryName(String lastDeliveryName) {
this.lastDeliveryName = lastDeliveryName;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getFirstDeliveryName() {
return firstDeliveryName;
}
public void setFirstDeliveryName(String firstDeliveryName) {
this.firstDeliveryName = firstDeliveryName;
}
public String getDeliveryAddress() {
return deliveryAddress;
}
public void setDeliveryAddress(String deliveryAddress) {
this.deliveryAddress = deliveryAddress;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
这就是最终对我起作用的原因
Order.java
package net.township.order;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Entity
@Table(name = "orders")
public class Order {
public Order() {
}
public Order(long merchantId, String firstDeliveryName, String lastDeliveryName, String deliveryAddress, String status, Date createDate, Date updateDate) {
this.merchantId = merchantId;
this.lastDeliveryName = lastDeliveryName;
this.firstDeliveryName = firstDeliveryName;
this.deliveryAddress = deliveryAddress;
this.status = status;
this.createDate = createDate;
this.updateDate = updateDate;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "order_id", unique = true)
private long orderId;
@Column(name = "merchant_id")
private long merchantId;
@Column(name = "first_delivery_name")
private String firstDeliveryName;
@Column(name = "last_delivery_name")
private String lastDeliveryName;
@Column(name = "delivery_address")
private String deliveryAddress;
@Column
private String status;
@OneToMany( cascade = CascadeType.ALL)
@JoinColumn(name = "order_id", referencedColumnName = "order_id")
private List<OrderItem> orderItems;
@Column(name = "create_date")
private Date createDate;
@Column(name = "update_date")
private Date updateDate;
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getMerchantId() {
return merchantId;
}
public void setMerchantId(long merchantId) {
this.merchantId = merchantId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public String getLastDeliveryName() {
return lastDeliveryName;
}
public void setLastDeliveryName(String lastDeliveryName) {
this.lastDeliveryName = lastDeliveryName;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getFirstDeliveryName() {
return firstDeliveryName;
}
public void setFirstDeliveryName(String firstDeliveryName) {
this.firstDeliveryName = firstDeliveryName;
}
public String getDeliveryAddress() {
return deliveryAddress;
}
public void setDeliveryAddress(String deliveryAddress) {
this.deliveryAddress = deliveryAddress;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
次要注释:CascadeType.ALL
,CascadeType.PERSIST
,CascadeType.MERGE
在某种程度上是多余的:CascadeType.ALL
已经包括了其他类型。不能在两个方向上进行级联,必须选择一个方向作为主方向,另一个方向作为从方向(如果不这样做,Hibernate通常会抛出错误)。默认情况下,集合始终是从属的。这是为了避免Hibernate无法解析的不一致架构。保存之前是否为OrderItems设置属性order
?是否可以共享服务?@Nikolay我不会手动设置这些对象的任何值。我的控制器将它们作为应用程序/json接收并转换。然后我使用CrudRepository执行保存。我的服务中的代码实际上就是userRepository.save(order)次要注释:CascadeType.ALL
,CascadeType.PERSIST
,CascadeType.MERGE
在某种程度上是多余的:CascadeType.ALL
已经包括了其他类型。不能在两个方向上进行级联,必须选择一个方向作为主方向,另一个方向作为从方向(如果不这样做,Hibernate通常会抛出错误)。默认情况下,集合始终是从属的。这是为了避免Hibernate无法解析的不一致架构。保存之前是否为OrderItems设置属性order
?是否可以共享服务?@Nikolay我不会手动设置这些对象的任何值。我的控制器将它们作为应用程序/json接收并转换。然后我使用CrudRepository执行保存。我的服务中的代码实际上就是userRepository.save(order)