使用JPA,Hibernate和Postgres,我有一个嵌入式集合的实体:
@ElementCollection
@CollectionTable(name = "arp_table", joinColumns = @JoinColumn(name = "bsvId"))
private Set<Row> rows;
可嵌入类是这样的:
@Embeddable
public class Row
{
@Column(name = "key")
private String key;
@Column(name = "value", nullable = true)
private Integer value;
...
}
,表格如下:
CREATE TABLE arp_table
(
bsv_id bigint NOT NULL,
key character varying(255) NOT NULL,
value int,
CONSTRAINT pk_arp_bsv_id_request_priority PRIMARY KEY (bsv_id, key),
CONSTRAINT fk_arp_bsv_id FOREIGN KEY (bsv_id)
REFERENCES bsv_table (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
(别担心,表格和列名称并非如此。)
请注意,value列可以为空。在尝试使用Map而不是Set时,我已经遇到了hibernate和null的问题。
当我更新实体时,hibernate会尝试删除集合的每一行,然后插入从集合中形成的行。但删除不起作用,因为生成的sql是:
delete from arp_table where ... and value = null
哪个不起作用,因为它应该说“value is null”。因此插入失败,重复密钥冲突。
所以我的问题是,我可以强制hibernate使用主键值或只是父实体的id删除行,而不是尝试匹配所有值吗?我想保留value列的可空性,因为null表示某些内容,value可以是任何int。
或者,当然,我做了一些根本错误的事情,因为这看起来非常简单。
答案 0 :(得分:1)
我会回答我自己的问题。不要将Set用于集合,请使用List。因为在Row类中没有实现equals()(并且不能,因为它没有包含实体的id),所以Set操作无法正常工作。我仍然不明白为什么在这种情况下,hibernate会单独删除每一行,而不仅仅是
delete from arp_table where bsv_id = ?;
但我现在确实有效。