JPA 在尝试插入(列活动)时复制列,并且不会在其中一个参数中插入值。
错误如下:
could not execute statement [No value specified for parameter 6.]
[insert into payment_item
(account_id,x,y,active,payment_id,active,id)
values (?,?,?,?,?,?,?)]
DDL 如下(为了解释而简化):
CREATE TABLE payment_item (
id BIGINT,
payment_id BIGINT NOT NULL,
active BOOLEAN NOT NULL DEFAULT true ,
PRIMARY KEY (id, active),
FOREIGN KEY (payment_id, active) REFERENCES payment (id, active)
) PARTITION BY LIST (active);
映射jpa:
public class PaymentItemKey implements Serializable {
private Long id;
private Boolean active = true;
}
@Entity
@Table(name = "payment_item")
@IdClass(PaymentItemKey.class)
public class PaymentItemEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "payment_item_generator")
@SequenceGenerator(name = "payment_item_generator", sequenceName = "payment_item_seq", allocationSize = 1)
private Long id;
@Id
private boolean active = true;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "payment_id", referencedColumnName = "id"),
@JoinColumn(name = "active", referencedColumnName = "active")
})
private PaymentEntity payment;
}
if 仅当我从主键中删除 active 时才有效。但这是必要的,因为我想使用活动列对表进行分区
请注意,如果我使用 Embedded 而不是 IdClass,则会出现相同的错误。
发生此错误是因为您试图声明具有相同名称的两个不同列。一列在代码
private boolean active = true;
中声明,第二列在代码 @JoinColumn(name = "active", referencedColumnName = "active")
中声明。要解决该问题,您需要删除其中一列或使用不同的名称。
我建议你去掉代码中的字段
private boolean active = true;
。由于 Payment
实体通过一对多关系与 PaymentItem
相关,因此其 active
字段会传播到每个嵌套项。
结果,我们得到以下映射。
@Entity
@IdClass(PaymentKey.class)
@Table(name = "payments")
public class Payment {
@Id
private Long id;
@Id
private Boolean active;
@JsonManagedReference
@OneToMany(mappedBy = "payment", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<PaymentItem> items;
// ...
}
@Entity
@Table(name = "payment_items")
public class PaymentItem {
@Id
private Long id;
@ManyToOne
@JsonBackReference
@JoinColumns({
@JoinColumn(name = "payment_id"),
@JoinColumn(name = "active")
})
private Payment payment;
// ...
}
public class PaymentKey implements Serializable {
private Long id;
private Boolean active;
// ...
}