![]() | |
| |
Primary Keys and Entity Identity
Every entity MUST HAVE a primary key.
The primary key MUST be defined on the entity that is the root of the entity hierarchy or on a mapped superclass of the entity hierarchy. The primary key MUST be defined EXACTLY ONCE in an entity hierarchy.
A SIMPLE (i.e., non-composite) primary key must correspond to a single persistent field or property of the entity class. The Id annotation is used to denote a simple primary key.
Id Annotation
The Id annotation specifies the primary key property or field of an entity. The Id annotation may be applied in an entity or mapped superclass.
By default, the mapped column for the primary key of the entity is assumed to be the primary key of the primary table. If no Column annotation is specified, the primary key column name is assumed to be the name of the primary key property or field.
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Id {}
Example:
@Id
public Long getId() {
return id;
}
A COMPOSITE primary key MUST correspond to either a single persistent field or property OR to a set of such fields or properties as described below. A primary key class MUST be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The EmbeddedId and IdClass annotations are used to denote composite primary keys.
The primary key (or field or property of a composite primary key) should be one of the following types:
any Java primitive type
any primitive wrapper type
java.lang.String
java.util.Date
java.sql.Date
In general, however, approximate numeric types (e.g., floating point types) should NEVER be used in primary keys. Entities whose primary keys use types other than these will NOT be portable. If generated primary keys are used, ONLY INTEGRAL types will be portable. If java.util.Date is used as a primary key field or property, the temporal type should be specified as DATE.
The access type (field- or property-based access) of a primary key class is determined by the access type of the entity for which it is the primary key.
The following rules apply for composite primary keys:
The primary key class MUST be public and MUST HAVE a public no-arg constructor.
If property-based access is used, the properties of the primary key class MUST be public or protected.
The primary key class must be Serializable.
The primary key class MUST define equals and hashCode methods. The semantics of value equality for these methods must be consistent with the database equality for the database types to which the key is mapped.
A composite primary key MUST either be represented and mapped as an embeddable class or must be represented and mapped to multiple fields or properties of the entity class.
If the composite primary key class is mapped to multiple fields or properties of the entity class, the names of primary key fields or properties in the primary key class and those of the entity class MUST correspond and their types MUST be the same.
The application MUST NOT CHANGE the value of the primary key. The behavior is undefined if this occurs.
EmbeddedId Annotation
Use the @EmbeddedId annotation to specify an embeddable composite primary key class (usually made up of two or more primitive or Java object types) owned by the entity. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns.
The EmbeddedId annotation is applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable (note that the Id annotation is NOT used in the embeddable class).
There must be ONLY ONE EmbeddedId annotation and NO Id annotation when the EmbeddedId annotation is used.
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface EmbeddedId {}
Example:
@EmbeddedId protected EmployeePK empPK;
Example below shows a typical composite primary key class, annotated as @Embeddable:
@Embeddable
public class EmployeePK implements Serializable {
private String name;
private long id;
public EmployeePK() {}
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int hashCode() {
return (int) name.hashCode() + id;
}
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof EmployeePK)) return false;
if (obj == null) return false;
EmployeePK pk = (EmployeePK) obj;
return pk.id == id && pk.name.equals(name);
}
}
Example below shows how to configure an entity with this embeddable composite primary key class using the @EmbeddedId annotation:
@Entity
public class Employee implements Serializable {
EmployeePK primaryKey;
public Employee() {}
@EmbeddedId
public EmployeePK getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(EmployeePK pk) {
primaryKey = pk;
}
...
}
IdClass Annotation
The IdClass annotation is applied to an entity class or a mapped superclass to specify a composite primary key class that is mapped to multiple fields or properties of the entity.
The names of the fields or properties in the primary key class and the primary key fields or properties of the entity MUST CORRESPOND and their TYPES MUST BE THE SAME.
The Id annotation MUST also be applied to the corresponding fields or properties of the entity.
@Target({TYPE}) @Retention(RUNTIME)
public @interface IdClass {
Class value();
}
Example:
@Entity
@IdClass(com.acme.EmployeePK.class)
public class Employee {
@Id String empName;
@Id Date birthDay;
...
}
Example below shows a non-embedded composite primary key class (fields empName and birthDay MUST correspond in name and type to properties in the entity class):
public class EmployeePK implements Serializable {
private String empName;
private Date birthDay;
public EmployeePK() {}
public String getName() {
return empName;
}
public void setName(String name) {
empName = name;
}
public long getDateOfBirth() {
return birthDay;
}
public void setDateOfBirth(Date date) {
birthDay = date;
}
public int hashCode() {
return (int) empName.hashCode();
}
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof EmployeePK)) return false;
if (obj == null) return false;
EmployeePK pk = (EmployeePK) obj;
return pk.birthDay == birthDay && pk.empName.equals(empName);
}
}
Example below shows how to configure a JPA entity with this non-embedded composite primary key class using the @IdClass annotation. NOTE: Because entity class fields empName and birthDay are used in the primary key, you MUST also annotate them using the @Id annotation:
@IdClass(EmployeePK.class)
@Entity
public class Employee {
@Id String empName;
@Id Date birthDay;
...
}
|
|
|
|
Hosting provided by PerfoHost: KVM VPS. Unix VPS. Windows VPS. VPN. Domains. Dedicated servers. Colocation.