首页 > 解决方案 > jpa @OneToMany 地图似乎不可能

问题描述

数据库表(不完全是 SQL,但你明白了要点..)

definition (
  id int, -- PK
  type int,
  label varchar(20) -- definition label can change over time
)

asset (
  id int, -- PK
  -- other asset fields...
)

property (
  id int, -- PK
  asset_id int,      -- with FK to asset + on delete cascade
  definition_id int, -- with FK to definition + on delete cascade
  payload varchar(256)
)

定义 id int 到有效负载 (Map<int,String>) 的映射,如下所示,有效,但这不是我想要的。

[Asset class]
@ElementCollection
@CollectionTable(name = "properties", 
  joinColumns = {@JoinColumn(name = "asset_id", referencedColumnName = "id")})
@MapKeyColumn(name = "definition_id")
@Column(name = "payload")
Map<Integer,String> properties;

相反,我试图在我的资产类中有以下地图:

Map<Definition,String> properties;

但不知道该怎么做。@MapKeyJoinColumn 注释旨在从实体类型映射值中提取关系,因此我无法在下面完成此操作:

@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "properties", 
  joinColumns = {@JoinColumn(name = "asset_id", referencedColumnName = "id")},
  //inexistant - inverseJoinColumns = {@JoinColumn(name = "property_id", referencedColumnName = "id")})
@MapKeyJoinColumn(name = "definition_id")
Map<Definition,String> properties;

我想要一个值类型的映射值。我的“属性”表具有定义 ID,所以我真的只需要 jpa/hibernate 来加入实体键的表,而不是值。

有什么线索吗?

标签: javahibernatejpaone-to-manymapkeyjoincolumn

解决方案


来自评论者,这有效:

[Asset class]
@ElementCollection
@CollectionTable(name = "properties", 
  joinColumns = {@JoinColumn(name = "asset_id", referencedColumnName = "id")})
@MapKeyJoinColumn(name = "definition_id")
@Column(name = "payload")
Map<Definition,String> properties;

不直观的答案是强制 @MapKeyJoinColumn 和关键实体类型,而不管 @ElementCollection 是否存在。

我不知道这是否只是具有休眠功能的侥幸,还是 JPA 确实支持它。


推荐阅读