JPA嵌套属性的MapKey

3

我有三个类似于这样的元素:

public class ItemType {
  @Id
  private Long id = null;
  ...
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "itemTypeVO")
  @MapKey(name = "company.id")
  private Map<Long, ItemTypePurpose> purposeHash = null;
  ...
}


public class ItemTypePurpose {
  @Id
  private Long id = null;
  ...
  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "idcompany")
  private Company company = null;
  ...
}

public class Company {
  @Id
  private Long id = null;
  ...
}

我的问题是,我想把公司的ID作为ItemType中我的映射表的键。
我可以编译和部署应用程序而不出现任何错误。可以将ItemType持久化,一切都很顺利地存储到数据库中。但是当我重新获取它时,映射表的键是“错误的”,我不知道使用了什么信息,但肯定不是公司ID。也许是ItemTypePurpose的ID。
公司被正确加载到Map中,只是映射表的键是错误的。我已经尝试过搜索,但找不到任何相关信息。是否有任何方法可以让JPA使用这个“嵌套属性”创建我的映射表?
*对于我的英语表示抱歉,如果您理解了我的需求并且能够更好地用英语撰写,请随意编辑我的问题。

1
我怀疑大多数人会将公司实例本身用作地图键。 - Chris
根据equals()和hash()方法的实现以及对象内部填充的数据,这可能是一个解决方案,否则map上的“get()”操作可能无法返回您的对象... - Rodrigo Leitão
2个回答

2

这并不能完全解决问题,但暂时满足了我的需求。

由于公司的ID在ItemTypePurpose表中,我可以将MapKey更改为:

public class ItemType {
  @Id
  private Long id = null;
  ...
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "itemTypeVO")
  @MapKeyColumn(name = "idcompany", insertable = false, updatable = false)
  private Map<Long, ItemTypePurpose> purposeHash = null;
  ...
}

我使用了@MapKeyColumn,而非@MapKey。 在@MapKeyColumn(name = "idcore_company", insertable = false, updatable = false中,将“关键信息”设置为只读,避免映射冲突,因为在ItemTypePurpose中使用相同的列来映射实体。

这不是具体的解决方案,但可以解决我的需求。 如果您想将字段作为Map Key其他ID,则此解决方案不适用。


0
晚回复了,但可以对其他人有所帮助。
@MapKeyColumn 似乎是这里的官方解决方案。根据文档,似乎要使用的注释取决于 Map 的键类型,而不管映射的字段如何。在您的情况下,键类型是 Long,因此将适用于以下内容:

https://docs.oracle.com/cd/E19226-01/820-7627/giqvn/index.html

在实体中使用映射集合
可以通过java.util.Map集合表示实体元素和关系的集合。Map由键和值组成。
如果Map的键类型是Java编程语言基本类型,可以使用javax.persistence.MapKeyColumn注释来设置键的列映射。默认情况下,@MapKeyColumn的name属性的格式为RELATIONSHIP字段/属性NAME_KEY。例如,如果引用关系字段名称为image,则默认名称属性为IMAGE_KEY。
总之: 对于嵌套字段,请使用MapKeyColumn(name =“myNestFiled_key”),然后在代码中手动设置值,例如:
ItemType.getPurposeHash().put(ItemTypePurpose.getCompany().getId(), ItemTypePurpose);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接