将子级添加到现有父级时休眠一对多 IntegrityConstraint

我有一个 Hibernate + Spring Boot 应用程序,并且在通过添加子项来更新父项时收到 IntegrityConstraintViolationException。


数据库架构是:


table order (

  id (primary key auto generated),

);


table order_line (

  order_id (primary key + foreign key to order.id),

  order_line_id (primary key set manually set in the code),

)

在java中:


@Getter

@Setter

@Entity(name = "ORDER")

public class Order {

    @Id

    @GeneratedValue(strategy= GenerationType.AUTO)

    private Integer id;



@Getter

@Setter

@Entity(name = "ORDER_LINE")

public class OrderLine implements Serializable{

    @Id

    private Integer orderLineId;

    @Id

    @ManyToOne(fetch = FetchType.LAZY)

    @JoinColumn(referencedColumnName = "id", columnDefinition = "Integer", insertable = false, updatable = false)

    private Order order;

要创建订单,我使用 JpaRepository 并创建我的对象,如下所示:


    Order order = new Order();

    order.setId(118); //This is an existing order ID which should be updated

    Set<OrderLine> orderLines = new HashSet<OrderLine>();


    OrderLine orderLine = new OrderLine();

    orderLine.setOrderLineId(0); //This is an existing order line

    orderLine.setOrder(order);

    orderLines.add(orderLine);


    orderLine = new OrderLine();

    orderLine.setOrderLineId(1); //This is a non-existing order line

    orderLine.setOrder(order);

    orderLines.add(orderLine);


    order.setOrderLines(orderLines);


    orderRepository.save(order);


for (OrderLine orderLine : order.getOrderLines()) {

    orderLine.setOrder(order);

}

orderRepository.save(order);

这段代码的作用是:

  • 创建具有 0、1 或更多孩子的新父母(意思是,我没有设置 orderId)

  • 更新父字段和/或任何子字段(在上面的示例中,如果我不添加第二个 orderLine,一切正常)

  • 删除子行

但是不起作用的是向现有父级添加一行。这会导致以下异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)的列“ORDER_LINE_ID”不能为空

我不明白,因为我可以清楚地看到每个 OrderLine 对象的 orderLineId 设置正确。

我究竟做错了什么?


开满天机
浏览 104回答 1
1回答

蓝山帝景

如果您想将 order_id 和 order_line_id 作为 OrderLine 实体中的复合键,则需要创建@Embeddable第一个:&nbsp;@Embeddable&nbsp;public class OrderLinePK implements Serializable {&nbsp; &nbsp; &nbsp; private Integer orderId;&nbsp; &nbsp; &nbsp; private Integer orderLineId;&nbsp;}&nbsp;并在您的 OrderLine 实体中将其更改为&nbsp;@EmbeddedId&nbsp;private OrderLinePk pk;&nbsp;@MapsId("orderId")&nbsp;@ManyToOne&nbsp;private Order order;现在每次您需要创建一个新的 OrderLine 时,您都必须创建一个主键对象并像这样分配 ID&nbsp;OrderLine orderLine = new OrderLine();&nbsp;OrderLinePK pk = new OrderLinePK();&nbsp;pk.setOrderLineId(11);&nbsp;orderLine.setPk(pk);&nbsp;orderLine.setOrder(order);希望这可以帮助。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java