JPA Persistence Fundamentals (Entity Lifecycle, Queries, Multiple Databases)
How Spring Boot Connects to a Database
Section titled “How Spring Boot Connects to a Database”Spring Boot connects using:
- JDBC Driver
- DataSource configuration
- Hibernate/JPA ORM
Add Dependencies
Section titled “Add Dependencies”<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId></dependency>Configure application.properties
Section titled “Configure application.properties”spring.datasource.url=jdbc:mysql://localhost:3306/testdbspring.datasource.username=rootspring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=trueEntity
Section titled “Entity”@Entitypublic class Employee {
@Id private Long id;
private String name;}Repository
Section titled “Repository”public interface EmployeeRepository extends JpaRepository<Employee, Long> {}Spring Boot automatically configures the DataSource, Hibernate, and transaction management.
Entity Lifecycle States
Section titled “Entity Lifecycle States”Entities move through four lifecycle states.
| State | Description |
|---|---|
| Transient | Object exists only in memory |
| Persistent | Managed by the persistence context |
| Detached | No longer managed by the persistence context |
| Removed | Marked for deletion |
Lifecycle Example
Section titled “Lifecycle Example”Employee emp = new Employee(); // Transient
entityManager.persist(emp); // Persistent
entityManager.detach(emp); // Detached
entityManager.remove(emp); // RemovedLifecycle Diagram
Section titled “Lifecycle Diagram”stateDiagram-v2
[*] --> Transient
Transient --> Persistent: persist()
Persistent --> Detached: detach()/session close
Persistent --> Removed: remove()
Detached --> Persistent: merge()
Removed --> [*]
save() vs saveAndFlush()
Section titled “save() vs saveAndFlush()”| Feature | save() | saveAndFlush() |
|---|---|---|
| Database write | During flush/commit | Immediately |
| Performance | Better | Slightly slower |
| Use case | Normal persistence | Immediate synchronization |
repository.save(employee);The entity is saved to the persistence context and written during flush or transaction commit.
repository.saveAndFlush(employee);The entity is immediately flushed to the database.
JPQL vs Native Queries
Section titled “JPQL vs Native Queries”| Feature | JPQL | Native SQL |
|---|---|---|
| Operates on | Entities | Tables |
| Database independent | Yes | No |
| Syntax | Object-oriented | SQL |
| Performance | Good | Sometimes faster |
@Query("SELECT e FROM Employee e WHERE e.name = :name")List<Employee> findByName(String name);Native Query
Section titled “Native Query”@Query(value = "SELECT * FROM employee WHERE name = ?1", nativeQuery = true)List<Employee> findByName(String name);Derived Query Methods
Section titled “Derived Query Methods”Spring Data JPA generates queries automatically from repository method names.
List<Employee> findByName(String name);
List<Employee> findBySalaryGreaterThan(double salary);
List<Employee> findByNameAndDepartment(String name, String department);Generated SQL equivalent:
SELECT * FROM employee WHERE name = ?;Common Keywords
Section titled “Common Keywords”| Keyword | Example |
|---|---|
| And | findByNameAndAge |
| Or | findByNameOrDept |
| Between | findBySalaryBetween |
| Like | findByNameLike |
| OrderBy | findByAgeOrderByName |
Configuring Multiple Databases
Section titled “Configuring Multiple Databases”Common use cases:
- Multi-tenant applications
- Separate read/write databases
- Microservices with multiple data sources
Configure Data Sources
Section titled “Configure Data Sources”spring.datasource.primary.url=jdbc:mysql://localhost:3306/db1spring.datasource.secondary.url=jdbc:mysql://localhost:3306/db2JPA Configuration
Section titled “JPA Configuration”@Configuration@EnableJpaRepositories( basePackages = "com.app.repo1", entityManagerFactoryRef = "entityManagerFactory1", transactionManagerRef = "transactionManager1")public class DB1Config {}Create a similar configuration for the second database.
Repository Separation
Section titled “Repository Separation”repo1 -> DB1repo2 -> DB2Key Takeaways
Section titled “Key Takeaways”- Entities move through four lifecycle states — Transient, Persistent, Detached, Removed — and understanding these explains a lot of confusing persistence-context behavior (e.g. why changes to a detached entity don’t get saved).
- Use
saveAndFlush()only when you need the write visible immediately (e.g. before a native query in the same transaction);save()is more efficient for normal use. - JPQL operates on entities and is database-independent; native SQL operates on tables and can be faster but ties you to a specific database.
- Derived query methods cover most simple queries without any JPQL; reach for
@Queryonce the method name would get unwieldy. - Multiple datasources require separate
EntityManagerFactory/TransactionManagerbeans per database, with repositories split by base package.