Agent Skills: Spring Data JPA Skill

Master Spring Data JPA - repositories, queries, relationships, transactions, and performance

spring-bootjparepositoriestransactionsperformance
backendID: pluginagentmarketplace/custom-plugin-spring-boot/spring-data-jpa

Skill Files

Browse the full folder contents for spring-data-jpa.

Download Skill

Loading file tree…

skills/spring-data-jpa/SKILL.md

Skill Metadata

Name
spring-data-jpa
Description
Master Spring Data JPA - repositories, queries, relationships, transactions, and performance

Spring Data JPA Skill

Comprehensive guide to data access with Spring Data JPA including repository patterns, custom queries, and performance optimization.

Overview

This skill covers everything needed for production-ready database access with Spring Data JPA.

Parameters

| Name | Type | Required | Default | Validation | |------|------|----------|---------|------------| | database | enum | ✗ | postgresql | postgresql | mysql | h2 | | migration_tool | enum | ✗ | flyway | flyway | liquibase | none | | fetch_strategy | enum | ✗ | lazy | lazy | eager |

Topics Covered

Core (Must Know)

  • Entities: @Entity, @Table, @Id, relationships
  • Repositories: JpaRepository, derived queries
  • Transactions: @Transactional, propagation

Intermediate

  • Custom Queries: @Query with JPQL and native SQL
  • Projections: Interface-based, class-based
  • Auditing: @CreatedDate, @LastModifiedDate

Advanced

  • Specifications: Dynamic query building
  • Entity Graphs: Fetch optimization
  • N+1 Prevention: JOIN FETCH strategies

Code Examples

Entity with Relationships

@Entity
@Table(name = "orders")
@EntityListeners(AuditingEntityListener.class)
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    private String orderNumber;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id", nullable = false)
    private Customer customer;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<OrderItem> items = new ArrayList<>();

    @CreatedDate
    private LocalDateTime createdAt;

    @Version
    private Long version;

    public void addItem(OrderItem item) {
        items.add(item);
        item.setOrder(this);
    }
}

Repository with Custom Queries

public interface OrderRepository extends JpaRepository<Order, Long>,
                                         JpaSpecificationExecutor<Order> {

    Optional<Order> findByOrderNumber(String orderNumber);

    @Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.customer.id = :customerId")
    List<Order> findByCustomerWithItems(@Param("customerId") Long customerId);

    @EntityGraph(attributePaths = {"items", "customer"})
    Optional<Order> findWithDetailsById(Long id);

    @Modifying
    @Query("UPDATE Order o SET o.status = :status WHERE o.id = :id")
    int updateStatus(@Param("id") Long id, @Param("status") OrderStatus status);
}

Specification Pattern

public class OrderSpecifications {

    public static Specification<Order> hasStatus(OrderStatus status) {
        return (root, query, cb) ->
            status == null ? null : cb.equal(root.get("status"), status);
    }

    public static Specification<Order> createdAfter(LocalDateTime date) {
        return (root, query, cb) ->
            date == null ? null : cb.greaterThan(root.get("createdAt"), date);
    }
}

// Usage
Specification<Order> spec = Specification
    .where(OrderSpecifications.hasStatus(status))
    .and(OrderSpecifications.createdAfter(since));
Page<Order> orders = orderRepository.findAll(spec, pageable);

Troubleshooting

Failure Modes

| Issue | Diagnosis | Fix | |-------|-----------|-----| | N+1 queries | Multiple SELECTs | Use @EntityGraph or JOIN FETCH | | LazyInitializationException | Access outside session | Use @Transactional or DTO | | Data not saved | Missing @Transactional | Add to service method |

Debug Checklist

□ Enable SQL logging: spring.jpa.show-sql=true
□ Check for N+1 with hibernate.generate_statistics
□ Verify @Transactional on write operations
□ Review fetch types (LAZY vs EAGER)

Unit Test Template

@DataJpaTest
@Testcontainers
class OrderRepositoryTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");

    @Autowired
    private OrderRepository orderRepository;

    @Test
    void shouldFindByOrderNumber() {
        Order order = new Order();
        order.setOrderNumber("ORD-001");
        orderRepository.save(order);

        Optional<Order> found = orderRepository.findByOrderNumber("ORD-001");
        assertThat(found).isPresent();
    }
}

Usage

Skill("spring-data-jpa")

Version History

| Version | Date | Changes | |---------|------|---------| | 2.0.0 | 2024-12-30 | Specifications, auditing, performance patterns | | 1.0.0 | 2024-01-01 | Initial release |