Identify correct and incorrect statements or examples about primary keys and entity identity, including the use of compound primary keys.

[Note]

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:

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 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;
	
	...
}
					

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     Free Mock Exam Engine