Spring Boot: From Basics to Production · Persistence with Spring Data JPA

Entities and Repositories

Map tables to entities and get CRUD for free with JpaRepository.

JPA entities map classes to tables with @Entity, @Id and column annotations; Hibernate is the default provider. Spring Data repositories (interface ProductRepository extends JpaRepository<Product, Long>) provide CRUD, paging and sorting with no implementation. Use GenerationType.IDENTITY or sequences for IDs, @Version for optimistic locking, and keep entities focused on persistence and invariants.

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @Column(name = "price_cents", nullable = false)
    private long priceCents;

    @Version
    private long version;

    protected Product() {}                      // required by JPA

    public Product(String name, long priceCents) {
        this.name = name;
        this.priceCents = priceCents;
    }

    public void changePrice(long newPriceCents) {
        if (newPriceCents < 0) throw new IllegalArgumentException("Price cannot be negative");
        this.priceCents = newPriceCents;
    }
    // getters ...
}

public interface ProductRepository extends JpaRepository<Product, Long> {
    Optional<Product> findByNameIgnoreCase(String name);
}

Common pitfalls

  • Using Lombok @Data on entities (equals/hashCode over lazy relations, mutable everything).
  • spring.jpa.hibernate.ddl-auto=update in production instead of migrations.
  • Exposing setters for every field, bypassing invariants.

Key points

  • Entities map tables; repositories give CRUD
  • @Version for optimistic locking
  • Schema via migrations, not ddl-auto

Further reading: Spring Data JPA: Getting started

Practice questions

Why shouldn't production use ddl-auto=update?

Answer

Hibernate may make unreviewed, partial or destructive schema changes and can't handle renames or data migrations; use versioned migrations (Flyway/Liquibase) and validate.

What does @Version do?

Answer

It adds optimistic locking: updates include WHERE version = ?, and if another transaction changed the row, an OptimisticLockException is thrown instead of silently overwriting.

Open in the app to mark lessons complete, take notes and track your progress.