JPA嵌套元素集合

huangapple go评论96阅读模式
英文:

JPA Nested Element Collection

问题

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

@Table
@Entity
public class MyClass {
   @Id
   private int myid;
   
   @ElementCollection
   private Map<String, List<String>> mymap;
}
英文:

I am trying to figure out if something like this type of Element Collection nesting is possible within JPA? Or at least doing something like this that would not require me to declare a new separate Entity which would hold the inner collection. I have seen usage of @MapKeyColumn & @CollectionTable with java Maps but, am not sure this would help solve.

@Table
@Entity
public class MyClass {
   @Id
   private int myid;
   
   @ElementCollection
   private Map&lt;String, List&lt;String&gt;&gt; mymap;
}

答案1

得分: 1

根据文档中的内容:

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. 适当的 Hibernate 映射:
@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;
}
英文:

According to the hibernate documentation:

> 2.8.2. Collections of value types
>
> Collections of value type include basic and embeddable types. Collections cannot be nested, and, when used in collections, embeddable types are not allowed to define other collections.
>
> For collections of value types, JPA 2.0 defines the @ElementCollection annotation. The lifecycle of the value-type collection is entirely controlled by its owning entity.

So, you should declare an intermediate entity to solve your problem. Below you can see a simple example.

  1. The database schema:
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. Appropriate hibernate mapping:
@Entity
@Table(name = &quot;MY_PATIENT&quot;)
public class Patient
{
   @Id
   @Column(name = &quot;PAT_RECID&quot;)
   private Long id;

   @Column(name = &quot;PAT_NAME&quot;)
   private String name;

   @OneToMany(mappedBy = &quot;patient&quot;)
   @MapKey(name = &quot;code&quot;)
   private Map&lt;String, Order&gt; orders;
}

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

   @Column(name = &quot;ORD_CODE&quot;)
   private String code;

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

   @ElementCollection
   @CollectionTable(name = &quot;MY_TEST&quot;, joinColumns = {@JoinColumn(name = &quot;TST_ORDID&quot;)})
   @Column(name = &quot;TST_CODE&quot;)
   private List&lt;String&gt; tests;
}

huangapple
  • 本文由 发表于 2020年4月3日 23:25:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/61015188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定