Arkhe-claude-plugins spring-boot-data-ddd
Spring Boot 4 data layer implementation for Domain-Driven Design. Use when implementing JPA or JDBC aggregates, Spring Data repositories, transactional services, projections, or entity auditing. Covers aggregate roots with AbstractAggregateRoot, value object mapping, EntityGraph for N+1 prevention, and Spring Boot 4 specifics (JSpecify null-safety, AOT repositories). For DDD concepts and design decisions, see the domain-driven-design skill.
git clone https://github.com/joaquimscosta/arkhe-claude-plugins
T=$(mktemp -d) && git clone --depth=1 https://github.com/joaquimscosta/arkhe-claude-plugins "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/spring-boot/skills/spring-boot-data-ddd" ~/.claude/skills/joaquimscosta-arkhe-claude-plugins-spring-boot-data-ddd && rm -rf "$T"
plugins/spring-boot/skills/spring-boot-data-ddd/SKILL.mdSpring Boot Data Layer for DDD
Implements DDD tactical patterns with Spring Data JPA and Spring Data JDBC in Spring Boot 4.
Technology Selection
| Choose | When |
|---|---|
| Spring Data JPA | Complex queries, existing Hibernate expertise, need lazy loading |
| Spring Data JDBC | DDD-first design, simpler mapping, aggregate-per-table, no lazy loading |
Spring Data JDBC enforces aggregate boundaries naturally—recommended for new DDD projects.
Core Workflow
- Define aggregate root → 2. Map value objects → 3. Create repository → 4. Implement service layer → 5. Add projections
See WORKFLOW.md for detailed step-by-step instructions with code examples.
Quick Patterns
See EXAMPLES.md for complete working examples including:
- Aggregate Root with AbstractAggregateRoot and domain events (Java + Kotlin)
- Repository with EntityGraph for N+1 prevention
- Transactional Service with proper boundaries
- Value Objects (Strongly-typed IDs, Money pattern)
- Projections for efficient read operations
- Auditing with automatic timestamps
Spring Boot 4 Specifics
- JSpecify null-safety:
and@NullMarked
annotations@Nullable - AOT Repository Compilation: Enabled by default for faster startup
- Jakarta EE 11: All imports use
namespacejakarta.* - ListCrudRepository: New interface returning
instead ofList<T>Iterable<T>
ListCrudRepository (Spring Data 3.1+)
New repository interface returning
List<T> for better API ergonomics:
// OLD: CrudRepository returns Iterable<T> public interface UserRepository extends CrudRepository<User, Long> { Iterable<User> findAll(); // Requires conversion to List } // NEW: ListCrudRepository returns List<T> public interface UserRepository extends ListCrudRepository<User, Long> { List<User> findAll(); // Direct List return List<User> findAllById(Iterable<Long> ids); // Also List } // Can also extend both for full functionality public interface UserRepository extends ListCrudRepository<User, Long>, ListPagingAndSortingRepository<User, Long> { }
Benefits: No more
StreamSupport.stream(iterable.spliterator(), false).toList() conversions.
Detailed References
- Workflow: See WORKFLOW.md for detailed step-by-step data layer implementation
- Examples: See EXAMPLES.md for complete working code examples
- Troubleshooting: See TROUBLESHOOTING.md for common issues and Boot 4 migration
- Aggregates & Entities: See references/AGGREGATES.md for complete patterns with value objects, typed IDs, auditing
- Repositories & Queries: See references/REPOSITORIES.md for custom queries, projections, specifications
- Transactions: See references/TRANSACTIONS.md for propagation, isolation, cross-aggregate consistency
Related Skills
| Need | Skill |
|---|---|
| DDD concepts and design | |
| REST API for aggregates | |
| Module boundaries | |
| Repository testing | |
Anti-Pattern Checklist
| Anti-Pattern | Fix |
|---|---|
on associations | Use + when needed |
| Returning entities from controllers | Convert to DTOs in service layer |
on private methods | Use public methods (proxy limitation) |
Missing on queries | Add for read operations (performance) |
| Direct aggregate-to-aggregate references | Reference by ID only |
| Multiple aggregates in one transaction | Use domain events for eventual consistency |
Critical Reminders
- One aggregate per transaction — Cross-aggregate changes via domain events
- Repository per aggregate root — Never for child entities
- Value objects are immutable — No setters, return new instances
- Flush before events — Call
before events dispatchrepository.save() - Test with
— Use@DataJpaTest
for setupTestEntityManager