Is it possible have two classes Template
and TemplateItem
, mapping to two database tables template
and template_item
, where they are joined using a Map<String, TemplateItem>
? If so can it be done using annotations?
The following results in three tables, ie adds an un-necessary mapping table.
@Entity
@Table(name = "template")
public class Template {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id")
private long id = 0;
@Column(name="开发者_C百科name")
private String name = "";
// Left side of map maps to name field of the item on the right side of the map.
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@MapKey(name = "name")
private Map<String, TemplateItem> items = new HashMap<String, TemplateItem>();
}
@Entity
@Table(name = "template_item")
public class TemplateItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id")
private long id = 0;
// The name field is the unique key for the Template.items Map
@Column(name="name")
private String name = "";
@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private Template template;
@Column(name="content")
private String content = "";
}
In mysql we get the three tables, the mapping table contains two columns copied out of the TemplateItem table:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | UNI | NULL | |
+-------------+--------------+------+-----+---------+----------------+
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| content | longtext | NO | | NULL | |
| name | varchar(120) | NO | | NULL | |
| template_id | bigint(20) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
+----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| at_template_id | bigint(20) | NO | PRI | NULL | |
| items_id | bigint(20) | NO | PRI | NULL | |
+----------------+------------+------+-----+---------+-------+
Standard JPA uses a join table for uni directional OneToMany
. Make the association bidirectional by specifying the owning side and you shouldn't get the join table:
@Entity
@Table(name = "template")
public class Template {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id")
private long id = 0;
@Column(name="name")
private String name = "";
// Left side of map maps to name field of the item on the right side of the map
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="template")
@MapKey(name = "name")
private Map items = new HashMap();
...
}
精彩评论