Jpa Patterns

by affaan-mef648e01899bNo license275K starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 3 days ago

Patrones JPA/Hibernate para diseño de entidades, relaciones, optimización de consultas, transacciones, auditoría, indexación, paginación y pooling en Spring Boot.

Instructions onlySoftware Development
AI-generated overview

Reference guidance for JPA/Hibernate entity design, relationships, query tuning, transactions and pooling in Spring Boot.

What it does
Provides conventions and code snippets for modeling JPA entities, mapping table indexes, and defining relationships such as @OneToMany and @ManyToOne. It covers N+1 prevention with fetch strategies and DTO projections, repository and pagination patterns, transaction annotations, auditing, soft deletes, HikariCP pooling settings, caching, migrations and data-access testing. It produces written guidance and example code rather than executable artifacts.
When to use it
Use when designing or reviewing JPA/Hibernate data models, repositories and table mappings in a Spring Boot application. It is also meant for performance tuning of queries, transactions, pagination, indexing and connection pooling.
Requirements
No scripts or tooling are bundled; it is instructions only. Applying the guidance assumes a Spring Boot project with JPA/Hibernate, and optionally Flyway or Liquibase, HikariCP, Testcontainers and a relational database.

Patrones JPA/Hibernate

Usar para modelado de datos, repositorios y ajuste de rendimiento en Spring Boot.

Cuándo Activar

  • Diseñar entidades JPA y mapeos de tablas
  • Definir relaciones (@OneToMany, @ManyToOne, @ManyToMany)
  • Optimizar consultas (prevención de N+1, estrategias de fetch, proyecciones)
  • Configurar transacciones, auditoría o soft deletes
  • Configurar paginación, ordenamiento o métodos de repositorio personalizados
  • Ajustar el connection pool (HikariCP) o caché de segundo nivel

Diseño de Entidades

java
@Entity@Table(name = "markets", indexes = {  @Index(name = "idx_markets_slug", columnList = "slug", unique = true)})@EntityListeners(AuditingEntityListener.class)public class MarketEntity {  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)  private Long id;
  @Column(nullable = false, length = 200)  private String name;
  @Column(nullable = false, unique = true, length = 120)  private String slug;
  @Enumerated(EnumType.STRING)  private MarketStatus status = MarketStatus.ACTIVE;
  @CreatedDate private Instant createdAt;  @LastModifiedDate private Instant updatedAt;}

Habilitar auditoría:

java
@Configuration@EnableJpaAuditingclass JpaConfig {}

Relaciones y Prevención de N+1

java
@OneToMany(mappedBy = "market", cascade = CascadeType.ALL, orphanRemoval = true)private List<PositionEntity> positions = new ArrayList<>();
  • Usar lazy loading por defecto; usar JOIN FETCH en consultas cuando sea necesario
  • Evitar EAGER en colecciones; usar proyecciones DTO para rutas de lectura
java
@Query("select m from MarketEntity m left join fetch m.positions where m.id = :id")Optional<MarketEntity> findWithPositions(@Param("id") Long id);

Patrones de Repositorio

java
public interface MarketRepository extends JpaRepository<MarketEntity, Long> {  Optional<MarketEntity> findBySlug(String slug);
  @Query("select m from MarketEntity m where m.status = :status")  Page<MarketEntity> findByStatus(@Param("status") MarketStatus status, Pageable pageable);}
  • Usar proyecciones para consultas ligeras:
java
public interface MarketSummary {  Long getId();  String getName();  MarketStatus getStatus();}Page<MarketSummary> findAllBy(Pageable pageable);

Transacciones

  • Anotar métodos de servicio con @Transactional
  • Usar @Transactional(readOnly = true) para rutas de lectura y optimizar
  • Elegir la propagación cuidadosamente; evitar transacciones de larga duración
java
@Transactionalpublic Market updateStatus(Long id, MarketStatus status) {  MarketEntity entity = repo.findById(id)      .orElseThrow(() -> new EntityNotFoundException("Market"));  entity.setStatus(status);  return Market.from(entity);}

Paginación

java
PageRequest page = PageRequest.of(pageNumber, pageSize, Sort.by("createdAt").descending());Page<MarketEntity> markets = repo.findByStatus(MarketStatus.ACTIVE, page);

Para paginación tipo cursor, incluir id > :lastId en JPQL con ordenamiento.

Indexación y Rendimiento

  • Agregar índices para filtros comunes (status, slug, claves foráneas)
  • Usar índices compuestos que coincidan con patrones de consulta (status, created_at)
  • Evitar select *; proyectar solo las columnas necesarias
  • Escrituras en lote con saveAll y hibernate.jdbc.batch_size

Connection Pooling (HikariCP)

Propiedades recomendadas:

spring.datasource.hikari.maximum-pool-size=20spring.datasource.hikari.minimum-idle=5spring.datasource.hikari.connection-timeout=30000spring.datasource.hikari.validation-timeout=5000

Para el manejo de LOB en PostgreSQL, agregar:

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

Caché

  • La caché de primer nivel es por EntityManager; evitar mantener entidades entre transacciones
  • Para entidades con muchas lecturas, considerar la caché de segundo nivel con cautela; validar la estrategia de evicción

Migraciones

  • Usar Flyway o Liquibase; nunca depender de auto DDL de Hibernate en producción
  • Mantener las migraciones idempotentes y aditivas; evitar eliminar columnas sin un plan

Pruebas de Acceso a Datos

  • Preferir @DataJpaTest con Testcontainers para replicar producción
  • Verificar la eficiencia SQL con logs: establecer logging.level.org.hibernate.SQL=DEBUG y logging.level.org.hibernate.orm.jdbc.bind=TRACE para valores de parámetros

Recuerda: Mantener las entidades ligeras, las consultas intencionales y las transacciones cortas. Prevenir N+1 con estrategias de fetch y proyecciones, e indexar para tus rutas de lectura/escritura.

Source and attribution

Source:affaan-m/eccindocs/es/skills/jpa-patternsat commitef648e0

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal