Spring Boot with Spring Data JPA
Add the Spring Data JPA starter to your project, define your first @Entity class, and connect Spring Boot to a real database.
Introduction
The CRUD controller you just built stores data in memory, which means every restart wipes it clean. Real applications need persistence — data that survives restarts, supports complex queries, and can be shared across multiple instances of your app. Spring Data JPA is the standard way Spring Boot applications talk to relational databases, and this lesson walks through adding it to a project, defining your first entity, and pointing it at a real database.
- What JPA and Hibernate are, and how they relate to each other.
- How to add the Spring Data JPA starter and a database driver.
- How to define an @Entity class that maps to a database table.
- How to configure a datasource connection in application.properties.
What is JPA?
JPA (Jakarta Persistence API, formerly Java Persistence API) is a specification that defines how Java objects map to relational database tables — a pattern known as Object-Relational Mapping (ORM). JPA itself is just an interface; it needs an implementation to actually do the work. Spring Boot uses Hibernate as its default JPA implementation, which handles translating your Java entities into SQL statements behind the scenes.
Spring Data JPA is a further layer on top of plain JPA/Hibernate, built by the Spring team. It removes almost all of the boilerplate normally needed to write data access code, letting you define a repository interface and get working CRUD methods for free — you'll see this in detail in the next lesson.
Adding the JPA Starter
Add spring-boot-starter-data-jpa to your pom.xml, along with a database driver. This example uses MySQL, but the setup is nearly identical for PostgreSQL or any other JPA-supported database.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope></dependency>spring-boot-starter-data-jpa brings in Hibernate as the JPA implementation, Spring Data JPA's repository support, and Spring's transaction management — everything needed to talk to a relational database with minimal configuration.
Your First @Entity
An entity is a plain Java class annotated with @Entity, marking it as something JPA should map to a database table. Each instance field typically becomes a column, and one field must be marked as the primary key with @Id.
import jakarta.persistence.Entity;import jakarta.persistence.GeneratedValue;import jakarta.persistence.GenerationType;import jakarta.persistence.Id;
@Entitypublic class Student {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String email;
public Student() {}
public Student(String name, String email) { this.name = name; this.email = email; }
public Long getId() { return id; } public void setId(Long id) { this.id = id; }
public String getName() { return name; } public void setName(String name) { this.name = name; }
public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}@GeneratedValue(strategy = GenerationType.IDENTITY) tells JPA to let the database itself generate the primary key value — using an auto-increment column — rather than assigning ids in application code.
Connecting a Real Database
Point Spring Boot at your database by adding datasource properties. Spring Boot auto-configures a DataSource bean and Hibernate's connection to it based entirely on these properties, with no additional Java configuration required.
spring.datasource.url=jdbc:mysql://localhost:3306/studentdbspring.datasource.username=rootspring.datasource.password=your_passwordspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=trueHow Hibernate Creates Tables
The spring.jpa.hibernate.ddl-auto property controls whether Hibernate manages your database schema automatically based on your @Entity classes, which is extremely convenient during development.
| Value | Behavior |
|---|---|
| none | Hibernate does nothing to the schema — you manage tables yourself |
| validate | Checks the schema matches your entities, fails to start if not |
| update | Adds missing tables/columns to match entities, never removes anything |
| create | Drops and recreates the schema every time the app starts |
| create-drop | Same as create, and also drops the schema when the app shuts down |
Click Run to see what this code prints.
Common Mistakes
- Using ddl-auto=create or create-drop against a production or shared database — it silently destroys existing data.
- Forgetting the @Id annotation entirely, which causes Spring Boot to fail at startup with a mapping exception.
- Mismatching the JDBC URL's database name with an actual existing database, causing a connection failure.
- Leaving spring.jpa.show-sql=true enabled in production, which floods logs with every generated SQL statement.
Best Practices
- Use ddl-auto=update only during early development, and switch to validate or none once you introduce a proper migration tool like Flyway or Liquibase.
- Never use create or create-drop against any database containing real data you care about.
- Keep entity classes focused on representing the table shape — put business logic in service classes instead.
- Store real database credentials outside application.properties using environment variables or a secrets manager once you deploy beyond your local machine.
Frequently Asked Questions
JPA is a specification — a set of interfaces and rules for ORM in Java. Hibernate is a concrete implementation of that specification, and it's the one Spring Boot uses by default. You code against JPA's annotations and interfaces, and Hibernate does the actual work underneath.
For basic CRUD operations, no — Spring Data JPA and Hibernate generate the SQL for you. You'll still write SQL or JPQL for more complex custom queries, which later lessons cover.
Yes. Swap the MySQL driver dependency for the PostgreSQL driver, and change the datasource URL and driver-class-name accordingly — the rest of your JPA code stays identical.
With ddl-auto=update, Hibernate adds new columns or tables to match the entity, but it never removes or renames existing columns — for that, you need a real migration tool.
Key Takeaways
- JPA is a specification for object-relational mapping; Hibernate is Spring Boot's default implementation of it.
- spring-boot-starter-data-jpa plus a database driver is all you need to connect Spring Boot to a relational database.
- @Entity marks a class as mapped to a table, and @Id marks its primary key field.
- spring.jpa.hibernate.ddl-auto controls whether Hibernate manages your schema automatically, and should never be create or create-drop in production.
Summary
Your Student class is now a real JPA entity backed by a real database table instead of an in-memory list. Next, you'll learn how Spring Data JPA repositories give you working save, find, and delete methods without writing any implementation code at all.