HHH-4933 Doc on Map and List support
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18911 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
95ab3e5ecc
commit
f32f68476b
|
@ -24,7 +24,7 @@
|
|||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
<chapter id="entity">
|
||||
<title>Entity Beans</title>
|
||||
<title>Mapping Entities</title>
|
||||
|
||||
<section id="entity-overview" revision="2">
|
||||
<title>Intro</title>
|
||||
|
@ -957,7 +957,7 @@ class UserId implements Serializable {
|
|||
identifier. In the database, it means that the
|
||||
<literal>Customer.user</literal> and the
|
||||
<literal>CustomerId.userId</literal> properties share the same
|
||||
underlying column (<literal>user_fk</literal> in this case). </para>
|
||||
underlying column (<literal>user_fk</literal> in this case).</para>
|
||||
|
||||
<para>In practice, your code only sets the
|
||||
<literal>Customer.user</literal> property and the user id value is
|
||||
|
@ -966,7 +966,7 @@ class UserId implements Serializable {
|
|||
|
||||
<warning>
|
||||
<para>The id value can be copied as late as flush time, don't rely
|
||||
on it until after flush time. </para>
|
||||
on it until after flush time.</para>
|
||||
</warning>
|
||||
|
||||
<para>While not supported in JPA, Hibernate lets you place your
|
||||
|
@ -1399,7 +1399,7 @@ public class Plane extends FlyingObject {
|
|||
</section>
|
||||
|
||||
<section id="entity-mapping-association">
|
||||
<title>Mapping entity bean associations/relationships</title>
|
||||
<title>Mapping entity associations/relationships</title>
|
||||
|
||||
<section>
|
||||
<title>One-to-one</title>
|
||||
|
@ -1493,7 +1493,7 @@ public class Passport implements Serializable {
|
|||
<literal>passport</literal> and the column id of <literal>Passport
|
||||
</literal>is <literal>id</literal>.</para>
|
||||
|
||||
<para>The third possibility (using an association table) is very
|
||||
<para>The third possibility (using an association table) is quite
|
||||
exotic.</para>
|
||||
|
||||
<programlisting>
|
||||
|
@ -1536,8 +1536,7 @@ public class Passport implements Serializable {
|
|||
<para>Many-to-one associations are declared at the property level with
|
||||
the annotation <literal>@ManyToOne</literal>:</para>
|
||||
|
||||
<programlisting>
|
||||
@Entity()
|
||||
<programlisting>@Entity()
|
||||
public class Flight implements Serializable {
|
||||
<emphasis role="bold">@ManyToOne</emphasis>( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
|
||||
@JoinColumn(name="COMP_ID")
|
||||
|
@ -1545,8 +1544,7 @@ public class Flight implements Serializable {
|
|||
return company;
|
||||
}
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
} </programlisting>
|
||||
|
||||
<para>The <literal>@JoinColumn</literal> attribute is optional, the
|
||||
default value(s) is like in one to one, the concatenation of the name
|
||||
|
@ -1563,8 +1561,7 @@ public class Flight implements Serializable {
|
|||
almost all cases. However this is useful when you want to use
|
||||
interfaces as the return type instead of the regular entity.</para>
|
||||
|
||||
<programlisting>
|
||||
@Entity()
|
||||
<programlisting>@Entity
|
||||
public class Flight implements Serializable {
|
||||
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, <emphasis
|
||||
role="bold">targetEntity=CompanyImpl.class</emphasis> )
|
||||
|
@ -1577,9 +1574,9 @@ public class Flight implements Serializable {
|
|||
|
||||
public interface Company {
|
||||
...
|
||||
</programlisting>
|
||||
}</programlisting>
|
||||
|
||||
<para>You can alse map a many to one association through an
|
||||
<para>You can also map a many-to-one association through an
|
||||
association table. This association table described by the
|
||||
<literal>@JoinTable</literal> annotation will contains a foreign key
|
||||
referencing back the entity table (through
|
||||
|
@ -1587,8 +1584,7 @@ public interface Company {
|
|||
referencing the target entity table (through
|
||||
<literal>@JoinTable.inverseJoinColumns</literal>).</para>
|
||||
|
||||
<programlisting>
|
||||
@Entity()
|
||||
<programlisting>@Entity
|
||||
public class Flight implements Serializable {
|
||||
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
|
||||
<emphasis role="bold">@JoinTable(name="Flight_Company",
|
||||
|
@ -1599,8 +1595,7 @@ public class Flight implements Serializable {
|
|||
return company;
|
||||
}
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
} </programlisting>
|
||||
</section>
|
||||
|
||||
<section id="entity-mapping-association-collections" revision="1">
|
||||
|
@ -1611,36 +1606,266 @@ public class Flight implements Serializable {
|
|||
<title>Overview</title>
|
||||
|
||||
<para>You can map <classname>Collection</classname>,
|
||||
<literal>List</literal> (ie ordered lists, not indexed lists),
|
||||
<literal>Map</literal> and <classname>Set</classname>. The EJB3
|
||||
specification describes how to map an ordered list (ie a list
|
||||
ordered at load time) using
|
||||
<literal>@javax.persistence.OrderBy</literal> annotation: this
|
||||
annotation takes into parameter a list of comma separated (target
|
||||
entity) properties to order the collection by (eg <code>firstname
|
||||
asc, age desc</code>), if the string is empty, the collection will
|
||||
be ordered by id. For true indexed collections, please refer to the
|
||||
<xref linkend="entity-hibspec" />. EJB3 allows you to map Maps using
|
||||
as a key one of the target entity property using
|
||||
<literal>@MapKey(name="myProperty")</literal> (myProperty is a
|
||||
property name in the target entity). When using
|
||||
<literal>@MapKey</literal> (without property name), the target
|
||||
entity primary key is used. The map key uses the same column as the
|
||||
property pointed out: there is no additional column defined to hold
|
||||
the map key, and it does make sense since the map key actually
|
||||
represent a target property. Be aware that once loaded, the key is
|
||||
no longer kept in sync with the property, in other words, if you
|
||||
change the property value, the key will not change automatically in
|
||||
your Java model (for true map support please refers to <xref
|
||||
linkend="entity-hibspec" />). Many people confuse
|
||||
<literal><map></literal> capabilities and
|
||||
<literal>@MapKey</literal> ones. These are two different features.
|
||||
<literal>@MapKey</literal> still has some limitations, please check
|
||||
the forum or the JIRA tracking system for more informations.</para>
|
||||
<classname>List</classname>, <classname>Map</classname> and
|
||||
<classname>Set</classname> pointing to associated entities as
|
||||
one-to-many or many-to-many associations using the
|
||||
<classname>@OneToMany</classname> or
|
||||
<classname>@ManyToMany</classname> annotation respectively. If the
|
||||
collection is of a basic type or of an embeddable type, use
|
||||
<classname>@ElementCollection</classname>. We will describe that in
|
||||
more detail in the following subsections but let's first focus on
|
||||
some semantic differences between the various collections.</para>
|
||||
|
||||
<para>Hibernate has several notions of collections.</para>
|
||||
<para>Lists can be mapped in two different ways:</para>
|
||||
|
||||
<para></para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>as ordered lists, the order is not materialized in the
|
||||
database</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>as indexed lists, the order is materialized in the
|
||||
database</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>To order lists in memory, add
|
||||
<literal>@javax.persistence.OrderBy</literal> to your property. This
|
||||
annotation takes into parameter a list of comma separated properties
|
||||
(of the target entity) and order the collection accordingly (eg
|
||||
<code>firstname asc, age desc</code>), if the string is empty, the
|
||||
collection will be ordered by the primary key of the target
|
||||
entity.</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
public class Customer {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
@OneToMany(mappedBy="customer")
|
||||
<emphasis role="bold">@OrderBy("number")</emphasis>
|
||||
public List<Order> getOrders() { return orders; }
|
||||
public void setOrders(List<Order> orders) { this.orders = orders; }
|
||||
private List<Order> orders;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Order {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
public String getNumber() { return number; }
|
||||
public void setNumber(String number) { this.number = number; }
|
||||
private String number;
|
||||
|
||||
@ManyToOne
|
||||
public Customer getCustomer() { return customer; }
|
||||
public void setCustomer(Customer customer) { this.customer = customer; }
|
||||
private Customer number;
|
||||
}
|
||||
|
||||
-- Table schema
|
||||
|-------------| |----------|
|
||||
| Order | | Customer |
|
||||
|-------------| |----------|
|
||||
| id | | id |
|
||||
| number | |----------|
|
||||
| customer_id |
|
||||
|-------------|</programlisting>
|
||||
|
||||
<para>To store the index value in a dedicated column, use the
|
||||
<classname>@javax.persistence.OrderColumn</classname> annotation on
|
||||
your property. This annotations describes the column name and
|
||||
attributes of the column keeping the index value. This column is
|
||||
hosted on the table containing the association foreign key. If the
|
||||
column name is not specified, the default is the name of the
|
||||
referencing property, followed by underscore, followed by
|
||||
<literal>ORDER</literal> (in the following example, it would be
|
||||
<literal>orders_ORDER</literal>).</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
public class Customer {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
@OneToMany(mappedBy="customer")
|
||||
<emphasis role="bold">@OrderColumn(name"orders_index")</emphasis>
|
||||
public List<Order> getOrders() { return orders; }
|
||||
public void setOrders(List<Order> orders) { this.orders = orders; }
|
||||
private List<Order> orders;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Order {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
public String getNumber() { return number; }
|
||||
public void setNumber(String number) { this.number = number; }
|
||||
private String number;
|
||||
|
||||
@ManyToOne
|
||||
public Customer getCustomer() { return customer; }
|
||||
public void setCustomer(Customer customer) { this.customer = customer; }
|
||||
private Customer number;
|
||||
}
|
||||
|
||||
-- Table schema
|
||||
|--------------| |----------|
|
||||
| Order | | Customer |
|
||||
|--------------| |----------|
|
||||
| id | | id |
|
||||
| number | |----------|
|
||||
| customer_id |
|
||||
| orders_index |
|
||||
|--------------|</programlisting>
|
||||
|
||||
<note>
|
||||
<para>We recommend you to convert
|
||||
<classname>@org.hibernate.annotations.IndexColumn</classname>
|
||||
usages to <classname>@OrderColumn</classname> unless you are
|
||||
making use of the base property. The <literal>base</literal>
|
||||
property lets you define the index value of the first element (aka
|
||||
as base index). The usual value is <literal>0</literal> or
|
||||
<literal>1</literal>. The default is 0 like in Java.</para>
|
||||
</note>
|
||||
|
||||
<para>Likewise, maps can borrow their keys from one of the
|
||||
associated entity properties or have dedicated columns to store an
|
||||
explicit key.</para>
|
||||
|
||||
<para>To use one of the target entity property as a key of the map,
|
||||
use <literal>@MapKey(name="myProperty")</literal>
|
||||
(<literal>myProperty</literal> is a property name in the target
|
||||
entity). When using <literal>@MapKey</literal> (without property
|
||||
name), the target entity primary key is used. The map key uses the
|
||||
same column as the property pointed out: there is no additional
|
||||
column defined to hold the map key, and it does make sense since the
|
||||
map key actually represent a target property. Be aware that once
|
||||
loaded, the key is no longer kept in sync with the property, in
|
||||
other words, if you change the property value, the key will not
|
||||
change automatically in your Java model.</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
public class Customer {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
@OneToMany(mappedBy="customer")
|
||||
<emphasis role="bold">@MapKey(name"number")</emphasis>
|
||||
public Map<String,Order> getOrders() { return orders; }
|
||||
public void setOrders(Map<String,Order> order) { this.orders = orders; }
|
||||
private Map<String,Order> orders;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Order {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
public String getNumber() { return number; }
|
||||
public void setNumber(String number) { this.number = number; }
|
||||
private String number;
|
||||
|
||||
@ManyToOne
|
||||
public Customer getCustomer() { return customer; }
|
||||
public void setCustomer(Customer customer) { this.customer = customer; }
|
||||
private Customer number;
|
||||
}
|
||||
|
||||
-- Table schema
|
||||
|-------------| |----------|
|
||||
| Order | | Customer |
|
||||
|-------------| |----------|
|
||||
| id | | id |
|
||||
| number | |----------|
|
||||
| customer_id |
|
||||
|-------------|</programlisting>
|
||||
|
||||
<para>Otherwise, the map key is mapped to a dedicated column or
|
||||
columns. To customize things, use one of the following
|
||||
annotations:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>@<classname>MapKeyColumn</classname> if the map key is a
|
||||
basic type, if you don't specify the column name, the name of
|
||||
the property followed by underscore followed by
|
||||
<literal>KEY</literal> is used (for example
|
||||
<literal>orders_KEY</literal>).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@MapKeyEnumerated</classname> /
|
||||
<classname>@MapKeyTemporal</classname> if the map key type is
|
||||
respectively an enum or a <classname>Date</classname>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@MapKeyJoinColumn</classname>/<classname>@MapKeyJoinColumns</classname>
|
||||
if the map key type is another entity.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><classname>@AttributeOverride</classname>/<classname>@AttributeOverrides</classname>
|
||||
when the map key is a embeddable object. Use
|
||||
<literal>key.</literal> as a prefix for your embeddable object
|
||||
property names.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>You can also use <classname>@MapKeyClass</classname> to define
|
||||
the type of the key if you don't use generics (at this stage, you
|
||||
should wonder why at this day and age you don't use
|
||||
generics).</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
public class Customer {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
@OneToMany @JoinTable(name="Cust_Order")
|
||||
<emphasis role="bold">@MapKeyColumn(name"orders_number")</emphasis>
|
||||
public Map<String,Order> getOrders() { return orders; }
|
||||
public void setOrders(Map<String,Order> orders) { this.orders = orders; }
|
||||
private Map<String,Order> orders;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Order {
|
||||
@Id @GeneratedValue public Integer getId() { return id; }
|
||||
public void setId(Integer id) { this.id = id; }
|
||||
private Integer id;
|
||||
|
||||
public String getNumber() { return number; }
|
||||
public void setNumber(String number) { this.number = number; }
|
||||
private String number;
|
||||
|
||||
@ManyToOne
|
||||
public Customer getCustomer() { return customer; }
|
||||
public void setCustomer(Customer customer) { this.customer = customer; }
|
||||
private Customer number;
|
||||
}
|
||||
|
||||
-- Table schema
|
||||
|-------------| |----------| |---------------|
|
||||
| Order | | Customer | | Cust_Order |
|
||||
|-------------| |----------| |---------------|
|
||||
| id | | id | | customer_id |
|
||||
| number | |----------| | order_id |
|
||||
| customer_id | | orders_number |
|
||||
|-------------| |---------------|</programlisting>
|
||||
|
||||
<para>Let's now explore the various collection semantics based on
|
||||
the mapping you are choosing.</para>
|
||||
|
||||
<table>
|
||||
<title>Collections semantics</title>
|
||||
|
@ -1668,18 +1893,18 @@ public class Flight implements Serializable {
|
|||
|
||||
<entry>java.util.List, java.util.Collection</entry>
|
||||
|
||||
<entry>@org.hibernate.annotations.CollectionOfElements or
|
||||
@OneToMany or @ManyToMany</entry>
|
||||
<entry>@ElementCollection or @OneToMany or
|
||||
@ManyToMany</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>Bag semantic with primary key (withtout the
|
||||
<entry>Bag semantic with primary key (without the
|
||||
limitations of Bag semantic)</entry>
|
||||
|
||||
<entry>java.util.List, java.util.Collection</entry>
|
||||
|
||||
<entry>(@org.hibernate.annotations.CollectionOfElements or
|
||||
@OneToMany or @ManyToMany) and @CollectionId</entry>
|
||||
<entry>(@ElementCollection or @OneToMany or @ManyToMany) and
|
||||
@CollectionId</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
|
@ -1687,9 +1912,9 @@ public class Flight implements Serializable {
|
|||
|
||||
<entry>java.util.List</entry>
|
||||
|
||||
<entry>(@org.hibernate.annotations.CollectionOfElements or
|
||||
@OneToMany or @ManyToMany) and
|
||||
@org.hibernate.annotations.IndexColumn</entry>
|
||||
<entry>(@ElementCollection or @OneToMany or @ManyToMany) and
|
||||
(@OrderColumn or
|
||||
@org.hibernate.annotations.IndexColumn)</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
|
@ -1697,8 +1922,8 @@ public class Flight implements Serializable {
|
|||
|
||||
<entry>java.util.Set</entry>
|
||||
|
||||
<entry>@org.hibernate.annotations.CollectionOfElements or
|
||||
@OneToMany or @ManyToMany</entry>
|
||||
<entry>@ElementCollection or @OneToMany or
|
||||
@ManyToMany</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
|
@ -1706,75 +1931,20 @@ public class Flight implements Serializable {
|
|||
|
||||
<entry>java.util.Map</entry>
|
||||
|
||||
<entry>(@org.hibernate.annotations.CollectionOfElements or
|
||||
@OneToMany or @ManyToMany) and (nothing or
|
||||
@org.hibernate.annotations.MapKey/MapKeyManyToMany for true
|
||||
map support, OR @javax.persistence.MapKey</entry>
|
||||
<entry>(@ElementCollection or @OneToMany or @ManyToMany) and
|
||||
((nothing or @MapKeyJoinColumn/@MapKeyColumn for true map
|
||||
support) OR @javax.persistence.MapKey)</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<remark>So specifically, java.util.List collections without
|
||||
@org.hibernate.annotations.IndexColumn are going to be considered as
|
||||
<remark>Specifically, java.util.List collections without
|
||||
@OrderColumn or @IndexColumn are going to be considered as
|
||||
bags.</remark>
|
||||
|
||||
<para>Collection of primitive, core type or embedded objects is not
|
||||
supported by the EJB3 specification. Hibernate Annotations allows
|
||||
them however (see <xref linkend="entity-hibspec" />).</para>
|
||||
|
||||
<programlisting>@Entity public class City {
|
||||
@OneToMany(mappedBy="city")
|
||||
<emphasis role="bold">@OrderBy("streetName")</emphasis>
|
||||
public List<Street> getStreets() {
|
||||
return streets;
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@Entity public class Street {
|
||||
<emphasis role="bold">public String getStreetName()</emphasis> {
|
||||
return streetName;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public City getCity() {
|
||||
return city;
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
@Entity
|
||||
public class Software {
|
||||
@OneToMany(mappedBy="software")
|
||||
<emphasis role="bold">@MapKey(name="codeName")</emphasis>
|
||||
public Map<String, Version> getVersions() {
|
||||
return versions;
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="tbl_version")
|
||||
public class Version {
|
||||
<emphasis role="bold">public String getCodeName()</emphasis> {...}
|
||||
|
||||
@ManyToOne
|
||||
public Software getSoftware() { ... }
|
||||
...
|
||||
}</programlisting>
|
||||
|
||||
<para>So <literal>City</literal> has a collection of
|
||||
<literal>Street</literal>s that are ordered by
|
||||
<literal>streetName</literal> (of <literal>Street</literal>) when
|
||||
the collection is loaded. <literal>Software</literal> has a map of
|
||||
<literal>Version</literal>s which key is the
|
||||
<literal>Version</literal> <literal>codeName</literal>.</para>
|
||||
|
||||
<para>Unless the collection is a generic, you will have to define
|
||||
<literal>targetEntity</literal>. This is a annotation attribute that
|
||||
take the target entity class as a value.</para>
|
||||
<para>More support for collections are available via Hibernate
|
||||
specific extensions (see <xref linkend="entity-hibspec" />).</para>
|
||||
</section>
|
||||
|
||||
<section id="entity-mapping-association-collection-onetomany"
|
||||
|
@ -4171,4 +4341,4 @@ public interface Cuisine {
|
|||
}</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
|
|
@ -32,13 +32,17 @@ import javax.persistence.Column;
|
|||
|
||||
/**
|
||||
* Define the map key columns as an explicit column holding the map key
|
||||
* This is completly different from {@link javax.persistence.MapKey} which use an existing column
|
||||
* This is completely different from {@link javax.persistence.MapKey} which use an existing column
|
||||
* This annotation and {@link javax.persistence.MapKey} are mutually exclusive
|
||||
*
|
||||
* @deprecated Use {@link javax.persistence.MapKeyColumn}
|
||||
* This is the default behavior for Map properties marked as @OneToMany, @ManyToMany
|
||||
* or @ElementCollection
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Target({METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
@Deprecated
|
||||
public @interface MapKey {
|
||||
Column[] columns() default {};
|
||||
/**
|
||||
|
|
|
@ -31,13 +31,17 @@ import javax.persistence.JoinColumn;
|
|||
|
||||
/**
|
||||
* Define the map key columns as an explicit column holding the map key
|
||||
* This is completly different from {@link javax.persistence.MapKey} which use an existing column
|
||||
* This is completely different from {@link javax.persistence.MapKey} which use an existing column
|
||||
* This annotation and {@link javax.persistence.MapKey} are mutually exclusive
|
||||
*
|
||||
* @deprecated Use {@link javax.persistence.MapKeyJoinColumn} {@link javax.persistence.MapKeyJoinColumns}
|
||||
* This is the default behavior for Map properties marked as @OneToMany, @ManyToMany
|
||||
* or @ElementCollection
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Deprecated
|
||||
public @interface MapKeyManyToMany {
|
||||
JoinColumn[] joinColumns() default {};
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue