JPA is duplicating a column when trying to insert (column active) and it does not insert the value in one of the parameter.
The error is the following:
could not execute statement [No value specified for parameter 6.]
[insert into payment_item
(account_id,x,y,active,payment_id,active,id)
values (?,?,?,?,?,?,?)]
The DDL is the followinng (simplfied for the explanation):
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);
The mapping 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 only works if I remove active from the primary key. But it is necessary because I want to partition the table using active column
Note that if I use Embedded instead of IdClass it gives the same error.
This error occurs because you are trying to declare two different columns with the same name. One column is declared in the code private boolean active = true;
, the second column is declared in the code @JoinColumn(name = "active", referencedColumnName = "active")
. To solve the problem you need to get rid of one of the columns or use a different name.
I suggest you get rid of the field in the code private boolean active = true;
. Since the Payment
entity is related to PaymentItem
by a one-to-many relationship, its active
field is propagated to each nested item.
As a result, we get the following mapping.
@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", referencedColumnName = "id"),
@JoinColumn(name = "active", referencedColumnName = "active")
})
private Payment payment;
// ...
}
public class PaymentKey implements Serializable {
private Long id;
private Boolean active;
// ...
}