JPA - Entity Annotations

A key feature of EJB 3.0 and JPA is the ability to create entities that contain object-relational mappings by using (metadata) annotations rather than deployment descriptors (orm.xml) as in earlier versions.

JPA contains two type of annotations:

See Annotation Type Summary for the list reference of all standard Annotations.

3 - Annotations

3.1 - Class

3.1.1 - @Entity

All Entity class is annotated with an @Entity annotation, since this is a requirement for every JPA entity.

3.1.2 - @Table

@Table(name = "OWNERS", catalog = "", schema = "APP")

where :

• catalog is different depending on the database vendor. In the case of MySQL, the catalog is simply the database name.

If there are any unique constraints, the uniqueConstraints attribute is added to the @Table annotation.

3.1.3 - @XmlRootElement

This annotation is used by JAXB to map the entity to XML.

3.1.4 - @NamedQueries

@NamedQueries annotation encapsulates all the generated @NamedQuery annotations.

JPA named queries allow to define Java Persistence Query Language (JPQL) queries right in the corresponding JPA entity, which means that the queries don't need to be hard-coded in the code.

JPQL queries defined in @NamedQuery annotations can be accessed through the createNamedQuery()method in the JPA EntityManager.

Identifiers preceded by a colon (:) are named parameters (known as bind variable in the Oracle Database) . These parameters need to be replaced by the appropriate values before executing the query, which is done by invoking the setParameter() method on a Query object.

@NamedQueries({
@NamedQuery(name = "Owner.findAll", query = "SELECT o FROM Owner o"),
@NamedQuery(name = "Owner.findById", query = "SELECT o FROM Owner o WHERE o.id = :id"),
@NamedQuery(name = "Owner.findByFirstName", query = "SELECT o FROM Owner o WHERE o.firstName = :firstName"),
@NamedQuery(name = "Owner.findByLastName", query = "SELECT o FROM Owner o WHERE o.lastName = :lastName"),
@NamedQuery(name = "Owner.findByCity", query = "SELECT o FROM Owner o WHERE o.city = :city"),
@NamedQuery(name = "Owner.findByTelephone", query = "SELECT o FROM Owner o WHERE o.telephone = :telephone")})

3.2 - Field

3.2.1 - @Basic

A basic property handles a standard value that is persisted as-is to the database. Every non-static non-transient property (field or method) of an entity bean is considered persistent.

The @Basic annotation allows to declare the fetching strategy.

The @Basic annotation is followed by the @Column annotation to define the property of the database column:

• name
• nullable
• length

No annotation is equivalent to the @Basic annotation.

@Basic(optional = false)
@Column(name = "NAME", nullable = false, length = 100)
private String name;

public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}

where:

• the optional attribute with a false value prevents from attempting to persist an entity with a null value for the field that this annotation decorates.

3.2.2 - Identifier

For each entity, you must designate at least one of the following:

• one @Id
• one @EmbeddedId
• multiple @Id and an @IdClass

@Id

An Id property designates an identifier, such as a primary key.

All entity beans must declare one or more fields which together form the persistent identity of an instance.

An @Id annotation is followed by a @Column annotation defining the unique attribute.

@Id()
@Column(name = "ID", unique = true, nullable = false, updatable=false)
private String id;

public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}

@EmbeddedId is used to model composite primary keys which is defined with an additional class

@EmbeddedId
protected ClientPK clientPK;

3.2.3 - @GeneratedValue

The JPA primary key generation strategy is denoted by the @GeneratedValue annotation.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "id", nullable = false)
private Integer id;
Strategy Generator Type (primary keys generated using)
AUTO (default) the most appropriate strategy for the underlying database.
TABLE An underlying database table to ensure uniqueness. (see @TableGenerator)
SEQUENCE A database sequence (see @SequenceGenerator)
IDENTITY A database identity column. The persistence provider must reread the inserted row from the table after an insert has occurred. Note: IDENTITY strategy is supported on Sybase, DB2, SQL Server, MySQL, Derby, JavaDB, Informix, and Postgres databases.

The persistence provider needs to have a persistent resource, such as a table or a sequence. The persistence provider cannot always rely upon the database connection that it obtains from the server to have permissions to create a table in the database. There will need to be a creation phase or schema generation to cause the resource to be created before the strategy can function.

3.2.4 - @Column

@Column(name = "ID", nullable = false)
• For attributes of type String, length to specify the maximum length allowed
• For decimal types, the precision (number of digits in a number) and scale (number of digits to the right of the decimal point)

The attribute definitions of the column annotation are used for regenerating the database tables from the JPA entities whereas the @NotNull and the @Size annotations are part of Bean Validation (A new feature introduced in Java EE 6).

3.3 - Property

3.3.1 - Access

The access property define where the annotation are written:

3.4 - Relationship

Bi-directional: A pet have an owner but an owner have also a pet (two directions).

3.4.1 - @One-to-One

The following @JoinColumn annotation declares the column in the (targeted|other) entity that will be used for the join.

//bi-directional one-to-one association to Technician
@OneToOne
@JoinColumn(name="ID")
private Technician technician;

public Technician getTechnician() {
return this.technician;
}
public void setTechnician(Technician technician) {
this.technician = technician;
}

3.4.2 - @Many-to-one

To define a many-to-one relationship, the following annotations are used:

• @Many-to-one: to define the cardinality
• @JoinColumn: to give the column name which joins to the primary key of the outer table (by default) in order to define the join predicate
// Order Class

// Cardinality Definition : Many orders can have one customer.
@ManyToOne
// Join column of the order table to the primary key of customer
@JoinColumn(name="CUSTOMERID")
// One Order has only one customer
private Customer customer;

// Getter and Setter
public Customer getCustomer () {
return this.customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}

The many-to-one annotation can define a fetch attribute that specifies when the field's persisted data are loaded:

• FetchType.EAGER: The data are loaded before the entity object is returned by the persistence provider.
• FetchType.LAZY: The data are loaded later, when the property is accessed.

The many-to-one are defaulted to FetchType.EAGER.