Defining Entities in JPA
From the JPA specification, we will retain that an entity is a lightweight persistence domain object. Typically, an entity represents a table in a relational database, and each entity instance corresponds to a row in that table.
An entity class must follow these requirements.
In particular, it must be annotated with the jakarta.persistence.Entity annotation.
Let’s review the entity classes for a very simple ecommerce data model.
1import jakarta.persistence.Entity;
2import jakarta.persistence.GeneratedValue;
3import jakarta.persistence.GenerationType;
4import jakarta.persistence.Id;
5import jakarta.persistence.Table;
6
7@Entity
8@Table(name = "products")
9public class Product {
10
11 @Id
12 @GeneratedValue(strategy = GenerationType.IDENTITY)
13 private Long id;
14
15 private String name;
16
17 private double price;
18
19 public Long getId() {
20 return id;
21 }
22
23 public String getName() {
24 return name;
25 }
26
27 public void setName(String name) {
28 this.name = name;
29 }
30
31 public double getPrice() {
32 return price;
33 }
34
35 public void setPrice(double price) {
36 this.price = price;
37 }
38
39}Each property maps to a column.
Primary keys are annotated with the @Id annotation.
1import jakarta.persistence.Entity;
2import jakarta.persistence.FetchType;
3import jakarta.persistence.GeneratedValue;
4import jakarta.persistence.GenerationType;
5import jakarta.persistence.Id;
6import jakarta.persistence.JoinColumn;
7import jakarta.persistence.ManyToOne;
8import jakarta.persistence.Table;
9
10@Entity
11@Table(name = "order_lines")
12public class OrderLine {
13
14 @Id
15 @GeneratedValue(strategy = GenerationType.IDENTITY)
16 private Long id;
17
18 private int quantity;
19
20 @ManyToOne
21 private Product product;
22
23 @ManyToOne(fetch = FetchType.LAZY)
24 @JoinColumn(name = "order_id")
25 private Order order;
26
27 public Long getId() {
28 return id;
29 }
30
31 public int getQuantity() {
32 return quantity;
33 }
34
35 public void setQuantity(int quantity) {
36 this.quantity = quantity;
37 }
38
39 public Product getProduct() {
40 return product;
41 }
42
43 public void setProduct(Product product) {
44 this.product = product;
45 }
46
47 public Order getOrder() {
48 return order;
49 }
50
51 public void setOrder(Order order) {
52 this.order = order;
53 }
54
55}@ManyToOne specifies a single-valued association to another entity class.
For example, an order line belongs to a single order, and is associated with a single product.
The fetch element tells the JPA implementation whether to load the associated entity (FetchType.EAGER, which is the default) or not (FetchType.LAZY).
1import jakarta.persistence.CascadeType;
2import jakarta.persistence.Entity;
3import jakarta.persistence.GeneratedValue;
4import jakarta.persistence.GenerationType;
5import jakarta.persistence.Id;
6import jakarta.persistence.OneToMany;
7import jakarta.persistence.Table;
8
9import java.util.ArrayList;
10import java.util.List;
11
12@Entity
13@Table(name = "orders")
14public class Order {
15
16 @Id
17 @GeneratedValue(strategy = GenerationType.IDENTITY)
18 private Long id;
19
20 private String customer;
21
22 @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
23 private List<OrderLine> orderLines = new ArrayList<>();
24
25 public Long getId() {
26 return id;
27 }
28
29 public String getCustomer() {
30 return customer;
31 }
32
33 public void setCustomer(String customer) {
34 this.customer = customer;
35 }
36
37 public List<OrderLine> getOrderLines() {
38 return orderLines;
39 }
40
41 public void setOrderLines(List<OrderLine> orderLines) {
42 this.orderLines.clear();
43 if (orderLines != null) {
44 for (OrderLine ol : orderLines) {
45 addOrderLine(ol);
46 }
47 }
48 }
49
50 public void addOrderLine(OrderLine ol) {
51 ol.setOrder(this);
52 this.orderLines.add(ol);
53 }
54
55 public void removeOrderLine(OrderLine ol) {
56 ol.setOrder(null);
57 this.orderLines.remove(ol);
58 }
59
60}It is common to map @ManyToOne relationships in both directions using the @OneToMany annotation.
In this case, the mappedBy element is added to reference the inverse @ManyToOne relationship.
The cascade element is used to specify the lifecycle of objects in the collection when the entity is deleted.
Here, we specify that deleting an order also deletes the related order lines.
There is no transitivity of deletion on products.