JPA 在插入时复制列。多列作为主键和外键

问题描述 投票:0回答:1

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,则会出现相同的错误。

java jpa foreign-keys
1个回答
0
投票

发生此错误是因为您试图声明具有相同名称的两个不同列。一列在代码

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;
    
  // ...
}

© www.soinside.com 2019 - 2024. All rights reserved.