JPA - Hibernate Annotations

Current Hibernate Version: 4.3.8.Final  Documentation

JPA Annotations - Contents:

AnnotationPackage Detail/Import statement
@Entityimport javax.persistence.Entity;
@Tableimport javax.persistence.Table;
@Columnimport javax.persistence.Column;
@Idimport javax.persistence.Id;
@GeneratedValueimport javax.persistence.GeneratedValue;
@Versionimport javax.persistence.Version;
@OrderByimport javax.persistence.OrderBy;
@Transientimport javax.persistence.Transient;
@Lobimport javax.persistence.Lob;
Hibernate Association Mapping Annotations
@OneToOneimport javax.persistence.OneToOne;
@ManyToOneimport javax.persistence.ManyToOne;
@OneToManyimport javax.persistence.OneToMany;
@ManyToManyimport javax.persistence.ManyToMany;
@PrimaryKeyJoinColumnimport javax.persistence.PrimaryKeyJoinColumn;
@JoinColumnimport javax.persistence.JoinColumn;
@JoinTableimport javax.persistence.JoinTable;
@MapsIdimport javax.persistence.MapsId;
Hibernate Inheritance Mapping Annotations
@Inheritanceimport javax.persistence.Inheritance;
@DiscriminatorColumnimport javax.persistence.DiscriminatorColumn;
@DiscriminatorValueimport javax.persistence.DiscriminatorValue;

@Entity

Annotate all your entity beans with @Entity. 

1
2
3
4
@Entity
public class Company implements Serializable {
...
}

@Table

Specify the database table this Entity maps to using the name attribute of @Table annotation. In the example below, the data will be stored in 'company' table in the database. 

1
2
3
4
5
@Entity
@Table(name = "company")
public class Company implements Serializable {
...
}

@Column

Specify the column mapping using @Column annotation.
1
2
3
4
5
6
7
8
9
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @Column(name = "name")
  private String name;
   
...
}

@Id

Annotate the id column using @Id.
1
2
3
4
5
6
7
8
9
10
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @Id
  @Column(name = "id")
  private int id;
   
...
}

@GeneratedValue

Let database generate (auto-increment) the id column.
1
2
3
4
5
6
7
8
9
10
11
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
...
}

@Version

Control versioning or concurrency using @Version annotation.
1
2
3
4
5
6
7
8
9
10
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @Version
  @Column(name = "version")
  private Date version;
   
...
}

@OrderBy

Sort your data using @OrderBy annotation. In example below, it will sort all contacts in a company by their firstname in ascending order.
1
2
@OrderBy("firstName asc")
private Set contacts;

@Transient

Annotate your transient properties with @Transient.

@Lob

Annotate large objects with @Lob.

Hibernate Association Mapping Annotations

Example App DB Schema

DB Schema 
The database for this tutorial is designed to illustrate various association mapping concepts. 
In RDBMS implementations, entities are joined using the following ways:
  • Shared Primary Key
  • Foreign Key
  • Association Table
In our example app,
  • Tables company and companyDetail have shared values for primary key. It is a one-to-one assoication.
  • Tables contact and contactDetail are linked through a foreign key. It is also a one to one association.
  • Tables contact and company are linked through a foriegn key in many-to-one association with contact being the owner.
  • Tables company and companyStatus are linked through a foreign key in many-to-one association with company being the owner.

@OneToOne

Hibernate Annotation Tip
  • Use @PrimaryKeyJoinColumn for associated entities sharing the same primary key.
  • Use @JoinColumn & @OneToOne mappedBy attribute when foreign key is held by one of the entities.
  • Use @JoinTable and mappedBy entities linked through an association table.
  • Persist two entities with shared key using @MapsId
For entities Company and CompanyDetail sharing the same primary key, we can associate them using @OneToOne and @PrimaryKeyJoinColumn as shown in the example below. 

Notice that the id property of CompanyDetail is NOT annotated with @GeneratedValue. It will be populated by id value of Company.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Entity
@Table(name = "company")
public class Company implements Serializable {
   
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private CompanyDetail companyDetail;
   
  ...
}
@Entity
@Table(name = "companyDetail")
public class CompanyDetail implements Serializable {
  @Id
  @Column(name = "id")
  private int id;
   
  ...
}
For entities Contact and ContactDetail linked through a foriegn key, we can use @OneToOne and @JoinColumn annotations. In example below, the id genereated for Contact will be mapped to 'contact_id' column of ContactDetail table. Please note the usage of @MapsId for the same.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Entity
@Table(name = "contactDetail")
public class ContactDetail implements Serializable {
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne
  @MapsId
  @JoinColumn(name = "contactId")
  private Contact contact;
   
  ...
}
@Entity
@Table(name = "contact")
public class Contact implements Serializable {
  @Id
  @Column(name = "ID")
  @GeneratedValue
  private Integer id;
  @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL)
  private ContactDetail contactDetail;
  ....
}
Also note that the relationship between Company and CompanyDetail is uni-directional. On the other hand, the relationship between Contact and Contact Detail is bi-directional and that can be achieved using 'mappedBy' attribute. 

The rationale to have one relationship as uni-directional and other as bi-directional in this tutorial is to illustrate both concepts and their usage. You can opt for uni-directional or bi-directional relationships to suit your needs.

@ManyToOne

Hibernate Annotation Tip
  • Use @JoinColumn when foreign key is held by one of the entities.
  • Use @JoinTable for entities linked through an association table.
The two examples below illustrate many-to-one relationships. Contact to Company and Company to CompanyStatus. Many contacts can belong to a company. Similary many companies can share the same status (Lead, Prospect, Customer) - there will be many companies that are currently leads.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Entity
@Table(name = "contact")
public class Contact implements Serializable {
  @ManyToOne
  @JoinColumn(name = "companyId")
  private Company company;
   
  ...
   
 }
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @ManyToOne
  @JoinColumn(name = "statusId")
  private CompanyStatus status;
   
  ...
   
 }

@OneToMany

Hibernate Annotation Tip
  • Use mappedBy attribute for bi-directional associations with ManyToOne being the owner.
  • OneToMany being the owner or unidirectional with foreign key - try to avoid such associations but can be achieved with @JoinColumn
  • @JoinTable for Unidirectional with association table
Please see the many-to-one relationship between Contact and Company above. Company to Contact will be a one-to-many relationship. The owner of this relationship is Contact and hence we will use 'mappedBy' attribute in Company to make it bi-directional relationship.
1
2
3
4
5
6
7
8
9
10
11
@Entity
@Table(name = "company")
public class Company implements Serializable {
  @OneToMany(mappedBy = "company", fetch = FetchType.EAGER)
  @OrderBy("firstName asc")
  private Set contacts;
     
  ...
   
 }
Again, for this tutorial, we have kept Company to CompanyStatus relationship as uni-directional.

@ManyToMany

Hibernate Annotation Tip
  • Use @JoinTable for entities linked through an association table.
  • Use mappedBy attribute for bi-directional association.

@PrimaryKeyJoinColumn

@PrimaryKeyJoinColumn annotation is used for associated entities sharing the same primary key. See OneToOne section for details.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
@Table(name = "company")
public class Company implements Serializable {
   
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private CompanyDetail companyDetail;
   
  ...
}

@JoinColumn

Use @JoinColumn annotation for one-to-one or many-to-one associations when foreign key is held by one of the entities. We can use @OneToOne or @ManyToOne mappedBy attribute for bi-directional relations. Also see OneToOne and ManyToOne sections for more details.
1
2
3
@ManyToOne
@JoinColumn(name = "statusId")
private CompanyStatus status;

@JoinTable

Use @JoinTable and mappedBy for entities linked through an association table.

@MapsId

Persist two entities with shared key (when one entity holds a foreign key to the other) using @MapsId annotation. See OneToOne section for details.
1
2
3
4
@OneToOne
@MapsId
@JoinColumn(name = "contactId")
private Contact contact;

Hibernate Inheritance Mapping Annotations

To understand Inheritance Mapping annotations, you must first understand Inheritance Mapping in Hiberate in detail. Once you understand Inheritance mapping concepts, please review below for annotations to be used.
  • table per class hierarchy - single table per Class Hierarchy Strategy: the <subclass> element in Hibernate
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Entity
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="planetype", discriminatorType=DiscriminatorType.STRING )
    @DiscriminatorValue("Plane")
    public class Plane { ... }
    @Entity
    @DiscriminatorValue("A320")
    public class A320 extends Plane { ... }
  • table per class/subclass - joined subclass Strategy: the <joined-subclass> element in Hibernate
  • 1
    2
    3
    4
    5
    6
    7
    @Entity
    @Inheritance(strategy=InheritanceType.JOINED)
    public class Boat implements Serializable { ... }
    @Entity
    @PrimaryKeyJoinColumn
    public class Ferry extends Boat { ... }
  • table per concrete class - table per Class Strategy: the <union-class> element in Hibernate
  • 1
    2
    3
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public class Flight implements Serializable { ... }
    Hibernate Annotation TipNote: This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY.

@Inheritance

See Hibernate Inheritance Mapping Annotations section for details.
1
2
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)

@DiscriminatorColumn

See Hibernate Inheritance Mapping Annotations section for details.
1
2
3
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="planetype", discriminatorType=DiscriminatorType.STRING )

@DiscriminatorValue

See Hibernate Inheritance Mapping Annotations section for details.
1
2
3
4
5
6
7
8
9
10
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="planetype", discriminatorType=DiscriminatorType.STRING )
@DiscriminatorValue("Plane")
public class Plane { ... }
@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }

No comments :

Post a Comment