将 child 添加到现有 parent 时休眠一对多 IntegrityConstraint
Hibernate One to Many IntegrityConstraint when adding child to existing parent
我有一个 Hibernate + Spring 引导应用程序,并且在通过添加 child.
更新 parent 时收到 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 并创建我的 objects 如下:
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);
这段代码的作用是:
正在创建一个新的 parent(意思是,我没有设置 orderId)0、1 或更多 children
更新 parent 字段 and/or 任何 children (在上面的示例中,如果我不添加第二个 orderLine,一切正常)
删除 child 行
但是不起作用的是向现有 parent 添加一行。这会导致以下异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Column 'ORDER_LINE_ID' cannot be null at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
我不明白,因为我可以清楚地看到每个 OrderLine objects 的 orderLineId 设置正确。
我做错了什么?
如果您想在 OrderLine 实体中同时使用 order_id 和 order_line_id 作为复合键,您需要先创建一个 @Embeddable
:
@Embeddable
public class OrderLinePK implements Serializable {
private Integer orderId;
private Integer orderLineId;
}
并在您的 OrderLine 实体中将其更改为
@EmbeddedId
private OrderLinePk pk;
@MapsId("orderId")
@ManyToOne
private Order order;
现在每次您需要创建一个新的 OrderLine 时,您都必须创建一个主键对象并像这样分配 ID
OrderLine orderLine = new OrderLine();
OrderLinePK pk = new OrderLinePK();
pk.setOrderLineId(11);
orderLine.setPk(pk);
orderLine.setOrder(order);
希望这对您有所帮助。
我有一个 Hibernate + Spring 引导应用程序,并且在通过添加 child.
更新 parent 时收到 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 并创建我的 objects 如下:
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);
这段代码的作用是:
正在创建一个新的 parent(意思是,我没有设置 orderId)0、1 或更多 children
更新 parent 字段 and/or 任何 children (在上面的示例中,如果我不添加第二个 orderLine,一切正常)
删除 child 行
但是不起作用的是向现有 parent 添加一行。这会导致以下异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'ORDER_LINE_ID' cannot be null at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
我不明白,因为我可以清楚地看到每个 OrderLine objects 的 orderLineId 设置正确。
我做错了什么?
如果您想在 OrderLine 实体中同时使用 order_id 和 order_line_id 作为复合键,您需要先创建一个 @Embeddable
:
@Embeddable
public class OrderLinePK implements Serializable {
private Integer orderId;
private Integer orderLineId;
}
并在您的 OrderLine 实体中将其更改为
@EmbeddedId
private OrderLinePk pk;
@MapsId("orderId")
@ManyToOne
private Order order;
现在每次您需要创建一个新的 OrderLine 时,您都必须创建一个主键对象并像这样分配 ID
OrderLine orderLine = new OrderLine();
OrderLinePK pk = new OrderLinePK();
pk.setOrderLineId(11);
orderLine.setPk(pk);
orderLine.setOrder(order);
希望这对您有所帮助。