【发布时间】:2017-05-20 19:49:53
【问题描述】:
我在使用休眠映射和审计时遇到了问题。 我的带有映射的 java 类:
@Entiy
@Audited
@Table(name = "farm_detail")
public class FarmDetail {
@Id
private Long id;
@ElementCollection
@MapKeyColumn(name = "field_id")
@Column(name = "remark")
@CollectionTable(name = "farm_detail_remark", joinColumns = @JoinColumn(name = "farm_detail_id"))
private Map<String, String> fieldRemarks = new HashMap<>();
// Getter, Setter, etc
}
farm_detail_remark和farm_detial_remark_aud表的sql定义:
db=# \d farm_detail_remark
Table "public.farm_detail_remark"
Column | Type | Modifiers
----------------+------------------------+-----------
farm_detail_id | bigint | not null
field_id | character varying(255) | not null
remark | character varying | not null
Indexes:
"farm_detail_remark_pkey" PRIMARY KEY, btree (farm_detail_id, field_id)
Foreign-key constraints:
"farm_detail_remark_farm_detail_id_fkey" FOREIGN KEY (farm_detail_id) REFERENCES farm_detail(id)
db=# \d farm_detail_remark_aud
Table "public.farm_detail_remark_aud"
Column | Type | Modifiers
----------------+------------------------+-----------
rev | integer | not null
revtype | smallint |
farm_detail_id | bigint | not null
field_id | character varying(255) | not null
remark | character varying |
Indexes:
"farm_detail_remark_aud_pkey" PRIMARY KEY, btree (rev, farm_detail_id, field_id)
Foreign-key constraints:
"farm_detail_remark_aud_rev_fkey" FOREIGN KEY (rev) REFERENCES revinfo(rev)
如果我想更新 fieldRemarks 集合的任何条目,我会在 farm_detail_remark_aud 表上收到重复键错误。通过打开 sql 日志,我发现 hibernate 尝试在 aud 表中插入两个条目:
Hibernate:
/* insert farm_detail_remark_AUD
*/ insert
into
farm_detail_remark_aud
(revtype, rev, farm_detail_id, remark, field_id)
values
(?, ?, ?, ?, ?)
21:20:58.188 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [1] as [INTEGER] - [0]
21:20:58.188 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [1057]
21:20:58.188 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [110]
21:20:58.188 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [4] as [VARCHAR] - [Old remark]
21:20:58.188 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [5] as [VARCHAR] - [152]
和(这里只有参数绑定):
21:20:58.193 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [1] as [INTEGER] - [2]
21:20:58.194 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [1057]
21:20:58.194 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [110]
21:20:58.194 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [4] as [VARCHAR] - [new remark]
21:20:58.194 [main] TRACE o.h.t.d.s.BasicBinder - binding parameter [5] as [VARCHAR] - [152]
有没有办法解决这个问题,而无需为备注创建额外的实体?
我使用的是 Spring Boot 1.5.7 附带的休眠 5.0.12。数据库是postgresql 9.5.6。
【问题讨论】:
-
因此,您实际上是在事务中通过键更新映射的值,导致与映射键的旧值相关的 REVTYPE=2 (DEL) 和与映射相关的 REVTYPE=0 (ADD)键的新值。
标签: hibernate jpa hibernate-mapping hibernate-envers