Skip to content
intermediate Phase · Java Backend Development

Entity

Learn how domain entities map to database tables.

30m
0 problems
Topic Progress 0%

JPA Entities

An entity is a Java class that maps to a database table. JPA (Java Persistence API) handles the mapping automatically.

Basic Entity

@Entity
@Table(name = "products")
public class Product {

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

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

    @Column(length = 2000)
    private String description;

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

    @Column(nullable = false)
    private Integer stockQuantity;

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

    @CreationTimestamp
    private LocalDateTime createdAt;

    @UpdateTimestamp
    private LocalDateTime updatedAt;

    // Constructors
    public Product() {}

    public Product(String name, String description, BigDecimal price, Integer stockQuantity) {
        this.name = name;
        this.description = description;
        this.price = price;
        this.stockQuantity = stockQuantity;
        this.active = true;
    }

    // Getters and Setters
    public Long getId() { return id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public BigDecimal getPrice() { return price; }
    public void setPrice(BigDecimal price) { this.price = price; }
    // ... other getters/setters
}

Key JPA Annotations

Annotation Purpose
@Entity Marks class as a JPA entity
@Table Specifies table name
@Id Marks primary key field
@GeneratedValue Auto-generates ID values
@Column Column configuration (name, nullable, length)
@CreationTimestamp Auto-sets on creation
@UpdateTimestamp Auto-updates on modification

Entity Relationships

One-to-Many (Category → Products):

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

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

    @Column(nullable = false)
    private String name;

    @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Product> products = new ArrayList<>();
}

Many-to-One (Product → Category):

@Entity
@Table(name = "products")
public class Product {

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id", nullable = false)
    private Category category;
}

Many-to-Many (Product ↔ Tag):

@Entity
@Table(name = "products")
public class Product {

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
        name = "product_tags",
        joinColumns = @JoinColumn(name = "product_id"),
        inverseJoinColumns = @JoinColumn(name = "tag_id")
    )
    private Set<Tag> tags = new HashSet<>();
}

Fetch Types

Type Behavior
FetchType.LAZY Load only when accessed (default for collections)
FetchType.EAGER Load immediately with parent (default for @ManyToOne)

Best Practice: Always use FetchType.LAZY and fetch eagerly only when needed with @EntityGraph or JPQL joins.

Entity Best Practices

Never Use Entities as API Responses

// BAD: Exposes internal data, causes lazy loading issues, circular references
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
    return productRepository.findById(id).orElseThrow();
    // Returns JSON with password hashes, internal fields, lazy-loaded collections
}

// GOOD: Convert to DTO
@GetMapping("/{id}")
public ProductDto getProduct(@PathVariable Long id) {
    return productService.getProduct(id);
    // Returns only the data the client needs
}

Avoid LazyInitializationException

// BAD: Lazy collection accessed outside transaction
@Entity
public class Order {
    @OneToMany(fetch = FetchType.LAZY)
    private List<OrderItem> items;
}

// In service — throws LazyInitializationException:
Order order = orderRepository.findById(id).orElseThrow();
order.getItems().size(); // Error! Transaction is closed

// SOLUTION 1: Fetch join in query
@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id")
Order findByIdWithItems(@Param("id") Long id);

// SOLUTION 2: Use @EntityGraph
@EntityGraph(attributePaths = {"items"})
@Query("SELECT o FROM Order o WHERE o.id = :id")
Order findByIdWithItems(@Param("id") Long id);

// SOLUTION 3: Use FetchType.EAGER (not recommended — causes N+1)

Entity Design Rules

  1. Private fields + getters/setters — encapsulation
  2. No-arg constructor required — JPA needs to instantiate entities
  3. Use @GeneratedValue — let the database generate IDs
  4. Use BigDecimal for money — never double/float
  5. Add @Column constraints — nullable, length, precision
  6. Use @CreationTimestamp/@UpdateTimestamp — for audit trail

Practice Problems

0 / 3 solved
Implement Entity

Design and implement a solution for Entity in a backend system. Consider scalability, error handling, and production readiness.

Solution
// Entity implementation
// Key aspects: validation, error handling, logging, testing

public class Entity {
    // Production-ready implementation
}
Entity Edge Cases

Identify and handle edge cases for Entity. What happens under high load, with invalid input, or during failures?

Solution
// Edge case handling:
// 1. Null/empty input -> validation
// 2. High load -> rate limiting, queuing
// 3. Failures -> retries, circuit breaker
// 4. Concurrent access -> locks, idempotency
Entity Testing Strategy

Write a testing strategy for Entity. Include unit tests, integration tests, and performance tests.

Solution
// Test plan:
// - Unit: 80% coverage target
// - Integration: API contracts
// - Performance: latency, throughput
// - Chaos: failure injection

Quiz

1. What is LazyInitializationException and how do you prevent it?

Question 1 options

2. Why should you use BigDecimal instead of double for prices?

Question 2 options

3. What is a common mistake when implementing Entity?

Question 3 options

Flashcards

Question

What does @Entity do?

Answer

Maps a Java class to a database table

Question

What is LazyInitializationException?

Answer

Error when accessing a lazy-loaded collection after the transaction closes

Question

Entity best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1. Entity = Java class mapped to a database table via JPA
  • 2. Use @Id, @GeneratedValue, @Column, @ManyToOne, @OneToMany etc.
  • 3. Always use FetchType.LAZY for collections
  • 4. Never expose entities directly as API responses — use DTOs
  • 5. Use BigDecimal for money, never double/float

Interview Tips

  • Explain N+1 problem and how to solve it
  • Know the difference between FetchType.LAZY and EAGER
  • Understand entity relationships (@ManyToOne, @OneToMany, @ManyToMany)

Cheat Sheet

JPA Entities

  • @Entity: Maps class to table
  • @Id + @GeneratedValue: Auto-generated primary key
  • Relationships: @ManyToOne, @OneToMany, @ManyToMany
  • FetchType.LAZY: Load on access (preferred)
  • Avoid: LazyInitializationException, N+1, double for money