Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何注释地图<;实体,整数>;和JPA一起?_Java_Hibernate_Jpa_Hashmap - Fatal编程技术网

Java 如何注释地图<;实体,整数>;和JPA一起?

Java 如何注释地图<;实体,整数>;和JPA一起?,java,hibernate,jpa,hashmap,Java,Hibernate,Jpa,Hashmap,我有这张地图: Map<Owner, Integer> ownerSharesMap = new HashMap<>(); 或 创建如下所示的类: public class Share{ int count; Owner owner } 然后保存此集合: Set<Share> shares; 设置共享; 你有什么建议?有没有办法用JPA注释第一张地图,或者我应该使用后面的解决方案 请注意,在我的项目中,查询性能是主要关注点,但我也需要干净的OO

我有这张地图:

Map<Owner, Integer> ownerSharesMap = new HashMap<>();
或 创建如下所示的类:

public class Share{
  int count;
  Owner owner
}
然后保存此集合:

Set<Share> shares;
设置共享;
你有什么建议?有没有办法用JPA注释第一张地图,或者我应该使用后面的解决方案

请注意,在我的项目中,查询性能是主要关注点,但我也需要干净的OOD


谢谢。

这在JPA中是可能的

映射集合中的值不是实体,因此需要使用
@ElementCollection
对其进行映射

映射可以很简单,如下所示:

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

您可以使用
@Column
注释指定集合表中的哪一列包含地图集合表的整数值。如果未指定,则默认为
OWNERSHARESMAP

@ElementCollection
@CollectionTable(name = "OWNER_SHARES", joinColumns = @JoinColumn(name = "SHARE_ID") )
@Column(name="SHARE_AMOUNT")
private Map<Owner, Integer> ownerSharesMap = new HashMap<Owner, Integer>();
如果未指定@MapKeyJoinColumn,则的默认列名将是元素集合属性的名称,并附加字符串“\u KEY”。因此,在我们的示例中,这将是
ownershieraresmap\u 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中生成模式:

Hibernate: 
    create table OWNER (
        OWNER_ID integer not null auto_increment,
        primary key (OWNER_ID)
    )
Hibernate: 
    create table OWNER_SHARES (
        SHARE_ID integer not null,
        SHARE_AMOUNT integer,
        OWNER_KEY integer not null,
        primary key (SHARE_ID, OWNER_KEY)
    )
Hibernate: 
    create table SHARE (
        SHARE_ID integer not null auto_increment,
        primary key (SHARE_ID)
    )
Hibernate: 
    alter table OWNER_SHARES 
        add constraint FK_th03t34g0d8hj7hmhppaa9juk 
        foreign key (OWNER_KEY) 
        references OWNER (OWNER_ID)
Hibernate: 
    alter table OWNER_SHARES 
        add constraint FK_smwhicxpq0ydqan5jn1p3goom 
        foreign key (SHARE_ID) 
        references SHARE (SHARE_ID)
以下是数据在表中的显示方式:


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

您是否了解名为“ElementCollection”的JPA2功能?我不确定我是否理解你的问题,但可能会帮助你。另请看一些@BrunoSilva,我需要的是映射:键是实体,值是基本的,谢谢完整的答案。让我检查一下,然后回来找你。太棒了!我已经找到了很多这样的答案,但这一个给了我我需要的解释如果你有不止一个Id作为地图的钥匙呢?您必须使用
@MapKeyJoinColumn
注释,而不是
@MapKeyJoinColumn
,并在注释中指定几个
@MapKeyJoinColumn
@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>();
@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>();
...
}
    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();
Hibernate: 
    create table OWNER (
        OWNER_ID integer not null auto_increment,
        primary key (OWNER_ID)
    )
Hibernate: 
    create table OWNER_SHARES (
        SHARE_ID integer not null,
        SHARE_AMOUNT integer,
        OWNER_KEY integer not null,
        primary key (SHARE_ID, OWNER_KEY)
    )
Hibernate: 
    create table SHARE (
        SHARE_ID integer not null auto_increment,
        primary key (SHARE_ID)
    )
Hibernate: 
    alter table OWNER_SHARES 
        add constraint FK_th03t34g0d8hj7hmhppaa9juk 
        foreign key (OWNER_KEY) 
        references OWNER (OWNER_ID)
Hibernate: 
    alter table OWNER_SHARES 
        add constraint FK_smwhicxpq0ydqan5jn1p3goom 
        foreign key (SHARE_ID) 
        references SHARE (SHARE_ID)