Real World Example

The ShopEase Product Entity

This is the complete Product entity used through the rest of the basic level — similar to what a Flipkart or Amazon seller catalogue stores:

package in.shopease.entity;

import jakarta.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Entity
@Table(name = "products",
       uniqueConstraints = @UniqueConstraint(name = "uk_products_sku", columnNames = "sku"),
       indexes = @Index(name = "idx_products_category", columnList = "category"))
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 40, updatable = false)
    private String sku;

    @Column(nullable = false, length = 150)
    private String name;

    @Column(length = 2000)
    private String description;

    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal price;

    @Column(nullable = false)
    private Integer stock = 0;

    @Column(length = 50)
    private String category;              // becomes @ManyToOne Category in the medium level

    @Enumerated(EnumType.STRING)
    @Column(nullable = false, length = 20)
    private ProductStatus status = ProductStatus.ACTIVE;

    @Column(nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @Transient
    public boolean isInStock() { return stock != null && stock > 0; }

    @PrePersist                            // lifecycle callback, runs just before INSERT
    void onCreate() { this.createdAt = LocalDateTime.now(); }

    protected Product() { }

    public Product(String sku, String name, BigDecimal price, Integer stock, String category) {
        this.sku = sku; this.name = name; this.price = price; this.stock = stock; this.category = category;
    }

    // getters and setters ...
}

Generated Table (MySQL)

Startup log

spring.jpa.hibernate.ddl-auto=create

Example output

Hibernate:
    create table products (
        price decimal(10,2) not null,
        stock integer not null,
        created_at datetime(6) not null,
        id bigint not null auto_increment,
        category varchar(50),
        sku varchar(40) not null,
        name varchar(150) not null,
        description varchar(2000),
        status enum ('ACTIVE','DISCONTINUED','OUT_OF_STOCK') not null,
        primary key (id)
    ) engine=InnoDB
Hibernate:
    create index idx_products_category on products (category)
Hibernate:
    alter table products
       add constraint uk_products_sku unique (sku)

Exercise

Exercise: Map the ShopEase Category entity: table categories, IDENTITY id, a required unique name (max 80 chars), a required unique slug (max 80 chars), an optional description (max 500), and a boolean active that defaults to true.

Show answer
@Entity
@Table(name = "categories")
public class Category {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true, length = 80)
    private String name;

    @Column(nullable = false, unique = true, length = 80)
    private String slug;

    @Column(length = 500)
    private String description;

    @Column(nullable = false)
    private boolean active = true;

    protected Category() { }

    public Category(String name, String slug) {
        this.name = name;
        this.slug = slug;
    }
    // getters and setters
}