2.2. Mapping with EJB3/JPA Annotations

EJB3 entities are plain POJOs. Actually they represent the exact same concept as the Hibernate persistent entities. Their mappings are defined through JDK 5.0 annotations (an XML descriptor syntax for overriding is defined in the EJB3 specification). Annotations can be split in two categories, the logical mapping annotations (allowing you to describe the object model, the class associations, etc.) and the physical mapping annotations (describing the physical schema, tables, columns, indexes, etc). We will mix annotations from both categories in the following code examples.
EJB3 annotations are in the javax.persistence.* package. Most JDK 5 compliant IDE (like Eclipse, IntelliJ IDEA and Netbeans) can autocomplete annotation interfaces and attributes for you (even without a specific "EJB3" module, since EJB3 annotations are plain JDK 5 annotations).
For more and runnable concrete examples read the JBoss EJB 3.0 tutorial or review the Hibernate Annotations test suite. Most of the unit tests have been designed to represent a concrete example and be a inspiration source.

2.2.1. Declaring an entity bean

Every bound persistent POJO class is an entity bean and is declared using the @Entity annotation (at the class level):
@Entity
public class Flight implements Serializable {
    Long id;

    @Id
    public Long getId() { return id; }

    public void setId(Long id) { this.id = id; }
}
@Entity declares the class as an entity bean (i.e. a persistent POJO class), @Id declares the identifier property of this entity bean. The other mapping declarations are implicit. This configuration by exception concept is central to the new EJB3 specification and a major improvement. The class Flight is mapped to the Flight table, using the column id as its primary key column.
Depending on whether you annotate fields or methods, the access type used by Hibernate will be field or property. The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access. Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type from the position of @Id or @EmbeddedId.

2.2.1.1. Defining the table

@Table is set at the class level; it allows you to define the table, catalog, and schema names for your entity bean mapping. If no @Table is defined the default values are used: the unqualified class name of the entity.
@Entity
@Table(name="tbl_sky")
public class Sky implements Serializable {
...
The @Table element also contains a schema and a catalog attributes, if they need to be defined. You can also define unique constraints to the table using the @UniqueConstraint annotation in conjunction with @Table (for a unique constraint bound to a single column, refer to @Column).
@Table(name="tbl_sky",
    uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})}
)
A unique constraint is applied to the tuple month, day. Note that the columnNames array refers to the logical column names.

2.2.1.2. Versioning for optimistic locking

You can add optimistic locking capability to an entity bean using the @Version annotation:
@Entity
public class Flight implements Serializable {
...
    @Version
    @Column(name="OPTLOCK")
    public Integer getVersion() { ... }
}
The version property will be mapped to the OPTLOCK column, and the entity manager will use it to detect conflicting updates (preventing lost updates you might otherwise see with the last-commit-wins strategy).
The version column may be a numeric (the recommended solution) or a timestamp as per the EJB3 spec. Hibernate support any kind of type provided that you define and implement the appropriate UserVersionType.
The application must not alter the version number set up by Hibernate in any way. To artificially increase the version number, check in Hibernate Entity Manager's reference documentation LockMode.WRITE