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
@Dataon entities (equals/hashCode over lazy relations, mutable everything). spring.jpa.hibernate.ddl-auto=updatein 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.