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
和JPA
OneToMany
注释的文档,我看不出哪里出了问题。我还要补充的是,我没有手动创建模式,而是让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)