JPA & Hibernate
Object-Relational Mapping (ORM) and Entities
Modern Java applications utilize Object-Relational Mapping (ORM) technologies to translate language objects and classes into database tables and rows.
1. Difference between JPA and Hibernate
There is a fundamental distinction between the specification standard and its concrete implementation engine:
Clic para ampliar
Detailed Persistence Diagram Explanation
- JPA (Jakarta Persistence API): A Java specification defining annotations (
@Entity,@Id,@Column) and contracts without containing executable logic. - Hibernate ORM: The default concrete engine chosen by Spring Boot. Reads JPA annotations, translates object operations into SQL dialect statements, and manages persistence sessions.
- Relational Database: Physical storage engine where tabular data resides.
2. JPA Entity Mapping and Annotations
An Entity is a POJO (Plain Old Java Object) representing a physical table. Each class instance corresponds to a row in the table.
2.1. Core Mapping Annotations
| Annotation | Purpose | Common Attributes |
|---|---|---|
@Entity | Declares the Java class as a JPA-managed entity. | name (logical entity name in JPQL) |
@Table | Specifies physical database table name. | name, schema, uniqueConstraints |
@Id | Marks field as Primary Key. | N/A |
@GeneratedValue | Specifies automatic primary key generation strategy. | strategy (IDENTITY, SEQUENCE, AUTO, TABLE) |
@Column | Configures column mapping details. | name, nullable, unique, length, precision |
@JoinColumn | Defines Foreign Key column name in relationships. | name, referencedColumnName, nullable |
@Transient | Specifies field should NOT be persisted in storage. | N/A |
3. Relational Database Model (ER Diagram)
Before writing Java code, we design the relational database schema for a product catalog domain:
Clic para ampliar
Detailed ER Diagram Explanation
CATEGORIES: Parent table storing product classifications (1 to N withPRODUCTS).SUPPLIERS: Parent table storing supplier companies (1 to N withPRODUCTS).PRODUCTS: Main table containing two Foreign Keys (FK):category_idandsupplier_id, physically referencing primary keys (PK) of parent tables.
4. Complete Java Entity Mapping with JPA and Lombok
Below, the ER diagram is mapped into Java entity classes using JPA and Lombok annotations:
4.1. Entity Category (Table categorias)
src/main/java/com/icesi/app/model/Category.java
package com.icesi.app.model;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Table(name = "categorias")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "nombre", nullable = false, length = 80)
private String name;
@Column(name = "descripcion", length = 255)
private String description;
}
4.2. Entity Supplier (Table proveedores)
src/main/java/com/icesi/app/model/Supplier.java
package com.icesi.app.model;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Table(name = "proveedores")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Supplier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "nombre_empresa", nullable = false, length = 100)
private String companyName;
@Column(name = "nit_ruc", unique = true, nullable = false, length = 50)
private String taxId;
}
4.3. Entity Product with @ManyToOne Relationships (Table productos)
src/main/java/com/icesi/app/model/Product.java
package com.icesi.app.model;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Table(name = "productos")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "nombre_producto", nullable = false, length = 120)
private String name;
@Column(name = "precio", nullable = false, precision = 10, scale = 2)
private Double price;
@Column(name = "codigo_sku", unique = true, nullable = false, length = 50)
private String sku;
// Transient field ignored by JPA
@Transient
private String temporaryDiscountCode;
// Many-to-One: Many products belong to one Category
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "categoria_id", nullable = false)
private Category category;
// Many-to-One: Many products are supplied by one Supplier
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "proveedor_id", nullable = false)
private Supplier supplier;
}
Self-Assessment Quiz
Cargando cuestionario...