Spring data access connects SQL operations to explicit transaction ownership and database constraints.
Learning roadmap
Read the contract, run the source-kit checks, and inspect a rejected input before extending the application. This subject covers Spring and Spring Boot together; Java language lessons remain in their own subject.
Prerequisites
Use Java object ownership, interfaces, exceptions and Maven builds before the framework-specific lessons.
Section lessons
- Spring JdbcTemplate: bound values and visible database constraints
- Spring TransactionTemplate: roll back a failed multi-row change
- Spring transactional methods: call paths and rollback assumptions
- Spring JPA entity lifecycle: managed changes and detached objects
- Spring JPA fetch plans: measure N+1 queries before changing mappings
- Spring JPA optimistic locking: reject a stale stock update
- Spring transaction propagation: joined rollback and independent commit
- Spring Data JPA repositories: derive a query from mapped properties
- Spring Data JPA projections: return selected fields without a full entity
- Spring Data keyset pagination: continue after the last stable identifier
- Spring transaction rollback: checked failures commit unless a rule says otherwise
- Spring transactional outbox: commit a receipt and event row together
- Spring outbox claims: move pending work once per database state
- Spring nested transactions: roll back one step to a JDBC savepoint
- Spring NESTED versus REQUIRES_NEW: savepoint or independent commit
- Spring outbox claims: allow recovery after a worker lease expires
- Outbox acknowledgements: require the current lease token
- Spring consumer deduplication: commit the event ID with the mutation
- Spring tenant command transaction: keep state, event and replay record together
- Spring JDBC versioned tenant update: inspect the affected row count
- Spring receipt outbox command: record intent without claiming delivery
- Spring outbox relay: claim, deliver, and acknowledge one event
- Spring outbox claims: lease expiry and token-fenced acknowledgement
- Spring consumer idempotency: reserve an event ID with the stock mutation
- Spring outbox transaction boundaries: where atomicity ends
- Spring scheduled relay: recover when the consumer commits before acknowledgement
- Spring outbox claim race: one conditional UPDATE wins
- Spring outbox lease renewal: extend only the current owner
- Spring database rollout: add a nullable column before changing every writer
- Spring database backfill: assign historical rows before enforcing ownership
- Spring database contract phase: reject old writers only after backfill
- Spring Boot migrations: what a versioned runner must add to the SQL test
- Flyway SQL migrations: record ordered schema changes against a real database
- Flyway expand and contract: show exactly when an old writer breaks
- Flyway validation: detect a changed applied migration before another write
- Spring Boot Flyway startup: apply versioned SQL before querying a receipt
- Spring Boot migration target: test an old writer before closing the schema
- Spring Boot migration history failure: stop context startup on a mismatch
Continue learning
Boot Foundations, Spring Core, Web APIs, Security, Testing, Production, Exercises, Quizzes, Projects.
Database concurrency limits
- Spring Boot JDBC pool capacity: size connections across replicas
- Spring transaction isolation: state the anomaly you need to prevent
New checked lessons
- Spring NamedParameterJdbcTemplate: expand an ID list without dropping tenant scope
- Spring SimpleJdbcInsert: read the generated key after one insert
Kafka and database ownership
- Spring Kafka duplicate delivery: let a unique event ID decide the second debit
- Spring outbox to Kafka: name the crash window between send and relay acknowledgement
GraphQL data and mutation limits
- Spring GraphQL list bounds: reject large arguments before reading rows
- Spring GraphQL mutation versions: reject a stale stock reservation
R2DBC subscription and transaction contracts
- Spring R2DBC subscription boundary: constructing SQL does not execute it
- Spring R2DBC named binds: keep a receipt identifier out of SQL syntax
- Spring R2DBC reactive transaction: roll back the event marker with a rejected debit
- Spring R2DBC conditional update: test tenant, version and stock floor in one statement
Spring AI boundary lessons
- Spring AI retrieval: apply the tenant filter before prompt assembly
- Spring AI conversation memory: partition by verified tenant and caller
Batch restart and recovery
- Spring Batch chunks: a later failure does not erase an earlier commit
- Spring Batch writers: use a stable source key when a chunk is replayed
Batch recovery and rejected-row review
- Spring Batch restart input: pin the manifest before resuming a cursor
- Spring Batch SkipListener: persist a rejection key with the skipped row
Batch metadata and hard-stop recovery
Persistence and transaction failure boundaries
- Spring Data JPA bulk update: the managed entity can still hold the old value
- Spring Data JPA derived delete versus bulk delete: callbacks and memory cost
- Spring Data JPA pessimistic lock: hold it only through the stock decision
- Spring REQUIRES_NEW: budget the second database connection
- Spring imperative transaction: a worker thread does not inherit it
- Spring reactive transaction: subscription owns the context, not a thread
MongoDB and Elasticsearch boundaries
- Spring Data MongoDB optimistic locking: save the version you read
- Spring Data MongoDB tenant uniqueness: enforce it in an index
- Spring Data MongoDB transaction: keep every write in one client session
- Spring Data MongoDB bulk writes: fewer round trips, different lifecycle behavior
- Spring Data MongoDB change stream: resume token and idempotent projection
- Spring Data Elasticsearch write versus search: refresh is the visibility boundary
- Spring Data Elasticsearch sequence conflict: do not overwrite a newer projection
- Spring Data Elasticsearch mapping rollout: build a new index, then move the read alias
Cassandra and Neo4j data boundaries
- Spring Data Cassandra partition keys: model the read before the row
- Spring Data Cassandra TTL: expiry is a storage and query cost
- Spring Data Cassandra paging state: continue the same bounded query
- Spring Data Neo4j relationships: save only the graph you own
- Spring Data Neo4j transaction: keep the command inside one managed unit
- Spring Data Neo4j version conflicts: reject a stale graph update
Cassandra and Neo4j write and query contracts
- Spring Data Cassandra conditional insert: reserve one key once
- Spring Data Cassandra consistency: budget availability and staleness per operation
- Spring Data Cassandra @Version: a conflict is not a merge
- Spring Data Neo4j custom query: return one coherent root record
- Spring Data Neo4j tenant lookup: constrain before traversing
- Spring Data Neo4j relationship properties: preserve edge identity
