首页 > 解决方案 > JPA 嵌套元素集合

问题描述

我想弄清楚在 JPA 中是否可以使用这种类型的元素集合嵌套?或者至少做这样的事情不需要我声明一个新的单独的实体来保存内部集合。我已经看到 @MapKeyColumn 和 @CollectionTable 与 java Maps 的用法,但是,我不确定这是否有助于解决。

@Table
@Entity
public class MyClass {
   @Id
   private int myid;

   @ElementCollection
   private Map<String, List<String>> mymap;
}

标签: javahibernatejpa

解决方案


根据休眠文档

2.8.2. 值类型的集合

值类型的集合包括基本类型和可嵌入类型。集合不能嵌套,并且在集合中使用时,可嵌入类型不允许定义其他集合。

对于值类型的集合,JPA 2.0 定义了@ElementCollection注解。值类型集合的生命周期完全由其拥有的实体控制。

因此,您应该声明一个中间实体来解决您的问题。下面你可以看到一个简单的例子。

  1. 数据库架构:
create table MY_PATIENT
(
   PAT_RECID  number,
   PAT_NAME varchar2(100),
   
   constraint PAT_PK primary key(PAT_RECID)
);

create table MY_ORDER
(
   ORD_RECID  number,
   ORD_CODE varchar2(15),
   ORD_PATID number,
   
   constraint ORD_PK primary key(ORD_RECID),
   constraint ORD_PAT_FK foreign key(ORD_PATID) references MY_PATIENT(PAT_RECID),
   constraint ORD_CODE_UNIQUE unique (ORD_CODE)
);

create table MY_TEST
(
   TST_RECID  number,
   TST_CODE varchar2(20),
   TST_ORDID number,
   
   constraint TST_PK primary key(TST_RECID),
   constraint TST_ORD_FK foreign key(TST_ORDID) references MY_ORDER(ORD_RECID),
   constraint TST_CODE_UNIQUE unique (TST_CODE)
);
  1. 适当的休眠映射:
@Entity
@Table(name = "MY_PATIENT")
public class Patient
{
   @Id
   @Column(name = "PAT_RECID")
   private Long id;

   @Column(name = "PAT_NAME")
   private String name;

   @OneToMany(mappedBy = "patient")
   @MapKey(name = "code")
   private Map<String, Order> orders;
}

@Entity
@Table(name = "MY_ORDER")
public class Order
{
   @Id
   @Column(name = "ORD_RECID")
   private Long id;

   @Column(name = "ORD_CODE")
   private String code;

   @ManyToOne
   @JoinColumn(name = "ORD_PATID")
   private Patient patient;

   @ElementCollection
   @CollectionTable(name = "MY_TEST", joinColumns = {@JoinColumn(name = "TST_ORDID")})
   @Column(name = "TST_CODE")
   private List<String> tests;
}

推荐阅读