如何使用JPA注释Map <entity,integer>?

时间:2015-10-21 18:58:09

标签: java hibernate jpa hashmap

我有这张地图:

Map<Owner, Integer> ownerSharesMap = new HashMap<>();

我知道如何将HashMap@OneToMany关系映射为原始类型作为关键字,但我搜索了很多内容并且没有找到方法来映射上面的{{1}与JPA。 我看到两个选择:

将我的HashMap更改为:(其中uuid是HashMap的关键列)

Owner

或 创建一个这样的类:

Map<UUID, Integer> ownerIdSharesMap = new HashMap<>();

然后坚持这个Set:

public class Share{
  int count;
  Owner owner
}
你有什么建议吗?有没有办法用JPA注释第一个Map,还是应该使用后面的解决方案?

请注意,在我的项目中,查询性能是主要问题,但我也想要干净的OOD。

感谢。

1 个答案:

答案 0 :(得分:10)

这可以在JPA中使用。

地图集合中的值不是实体,因此您需要使用float对其进行映射。

您的映射可以很简单:

@ElementCollection

虽然,您可以指定将存储值的集合表。使用@ElementCollection private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>(); 注释,您可以指定集合表的名称以及连接列。

@CollectionTable

如果未指定@ElementCollection @CollectionTable(name="OWNER_SHARES", joinColumns=@JoinColumn(name="SHARE_ID")) private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>(); ,则表名将默认为引用实体的名称,附加下划线和包含元素集合的实体属性的名称。在我们的示例中,这将是@CollectionTable。连接列默认值类似于引用实体的名称,附加下划线和实体表的主键列的名称。

您可以使用SHARE_OWNERSHARESMAP注释来指定集合表中哪个列所在的地图集合表的整数值。如果未指定,则默认为@Column

OWNERSHARESMAP

按实体键入时,并非实体的所有属性都将存储在集合表中。它只是将要存储的实体的主键。为此,我们将在集合表中添加一个列来存储映射的键,这是Owner实体主键的外键。要覆盖此列的名称,您可以使用@ElementCollection @CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") ) @Column(name="SHARE_AMOUNT") private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();

@MapKeyJoinColumn

如果未指定@MapKeyJoinColumn,则默认列名称将是元素集合属性的名称,并附加字符串&#34; _KEY&#34;。因此,在我们的示例中,这将是@ElementCollection @CollectionTable(name="OWNER_SHARES", joinColumns=@JoinColumn(name="SHARE_ID")) @Column(name="SHARE_AMOUNT") @MapKeyJoinColumn(name="OWNER_KEY") private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();

以下是您的实体在代码中的样子示例:

OWNERSHARESMAP_KEY

这是一个示例代码,用于保存实体及其集合:

@Entity
@Table(name="OWNER")
public class Owner {

    @Id
    @Column(name="OWNER_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer id;
...
}

@Entity
@Table(name = "SHARE")
public class Share {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "SHARE_ID")
    private Integer id;

    @ElementCollection
    @CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") )
    @Column(name="SHARE_AMOUNT")
    @MapKeyJoinColumn(name = "OWNER_KEY")
    private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
...
}

以下是Hibernate如何在MySQL中生成模式:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();

    Owner owner1 = new Owner();
    Owner owner2 = new Owner();

    em.persist(owner1);
    em.persist(owner2);

    Share share = new Share();
    share.getOwnerSharesMap().put(owner1, 20);
    share.getOwnerSharesMap().put(owner2, 40);

    em.persist(share);

    em.getTransaction().commit();

以下是表格中数据的外观:

enter image description here

您将在我的GitHub repo中看到此实现的示例。