
Common JPA annotations
In this chapter, we will create entities to represent a forum application. The main entities involved in a forum are the forum itself (which exposes the argument), the topic that exposes the questions of the argument, the posts (the responses), and the category of a forum.
So we can start with the upper level, the category:
@Entity
@Table(name = "JBP_FORUMS_CATEGORIES")
public class Category implements Serializable {
@Id
@Column(name = "JBP_ID")
@GeneratedValue
private Integer id;
}
The @Entity annotation specifies that the bean we have written is an entity. An entity is an object representing a table in a relational database. The @Table annotation maps the entity to the relational table of a database. If the @Table is not specified, the entity will be mapped with a relational table represented by the simple name of the class, in the case of the example it will be Category.
In this sample we have specified the primary key of the table thanks to the @Id annotation that declares a field as primary key. The @Column annotation maps the Java field to the field name of the relational table. The @GeneratedValue specifies that the key is automatically generated. This annotation follows the configurations of the database. So you can choose how to generate the key according to a strategy for example as SEQUENCE, IDENTITY, or TABLE. The default AUTO simply follows the configuration of the mapped table. You can also specify a custom generator that you can annotate as @TableGenerator or @SequenceGenerator. Here's a sample:
@TableGenerator(
name="empGen",
table="ID_GEN",
pkColumnName="GEN_KEY",
valueColumnName="GEN_VALUE",
pkColumnValue="EMP_ID",
allocationSize=1)
@Id
@GeneratedValue(strategy=TABLE, generator="empGen")
private Integer id;
The @Column annotation can be used for all fields of the table too. Here is a sample of the title field of the category:
@Column(name = "JBP_TITLE")
private String title;
The category has a one-to-many relationship with the Forum entity. Here is the forum:
@Entity
@Table(name = "JBP_FORUMS_FORUMS")
public class Forum implements Serializable {
private Category category;
...}
See now the Embeddable objects. Create a message object:
@Embeddable
public class Message implements Serializable, Cloneable {
@Column(name = "JBP_SUBJECT")
private String subject = "";
@Column(name = "JBP_TEXT")
private String text = "";
...
}
And a post entity:
@Entity
@Table(name = "JBP_FORUMS_POSTS")
public class Post implements Serializable {
@Embedded
private Message message;
}
@Embeddable is an alternative to the entity. An annotated class with @Embeddable doesn't represent a table on a database. It can be defined as a part of a table depending on who imports it. In this case, the post entity encapsulates the message, so in the end the fields of the post table will be JBP_SUBJECT and JBP_TEXT because they are imported by the Embeddable message.
All entities are inheritable. Consider the following sample:
@Entity
public class Pet {
...}
And an entity that extends pet:
@Entity
public class Dog extends Pet {
...}
As a result in the database, we will get one table called PET, and all data inserted through the Dog and Pet entity will end up in the PET table. By default, the entities use a inheritance strategy called SINGLE_TABLE. We can change this strategy through the @Inheritance annotation. There are two other inheritance strategies as well:
- TABLE PER CLASS: It works like SINGLE_TABLE except that the annotated class will create a new table. A sample:
@Entity
@Inheritance(strategy = TABLE_PER_CLASS)
public class Vehicle {...}
@Entity
public class Car extends Vehicle {...}
- JOINED: The extended class will be represented as a JOIN table while the extending class will provide a foreign key versus the JOIN table. Here is a sample of an inheritable class:
@Entity
@Table(name = "JBP_FORUMS_WATCH")
@Inheritance(strategy = JOINED)
public class Watch implements Serializable {
@Id
@Column(name = "JBP_ID")
@GeneratedValue
private Integer id;
@Column(name = "JBP_MODE")
private int mode;
}
A class extending Watch can be:
@Entity
@Table(name = "JBP_FORUMS_TOPICSWATCH")
public class TopicWatch extends Watch implements Serializable {..}
During the creation of the database, the Entity Manager engine will create two tables:
- JBP_FORUMS_WATCH: With ID and mode columns
- JBP_FORUMS_TOPICSWATCH: With a fk_TopicsWatch_Watch foreign key versus the JBP_FORUMS_WATCH table