Skip to main content

Command Palette

Search for a command to run...

Jakarta Persistence (JPA) en Quarkus: Acceso a Datos con EntityManager

Updated
3 min read

Introducción

Jakarta Persistence (JPA) es la especificación estándar para acceso a datos relacionales en Java. Quarkus implementa JPA completamente a través de Hibernate ORM, proporcionando todas las características de la especificación.

¿Qué es JPA?

JPA proporciona una API estándar para mapear objetos Java a tablas de base de datos relacionales. Permite trabajar con objetos en lugar de SQL directo, aunque también soporta SQL cuando es necesario.

EntityManager: El Corazón de JPA

El EntityManager es la interfaz principal para interactuar con la base de datos:

@Inject
EntityManager entityManager;

@Transactional
public Hero createHero(Hero hero) {
    entityManager.persist(hero);
    entityManager.flush();
    return hero;
}

Operaciones Básicas

CRUD Operations

// Create
entityManager.persist(hero);

// Read
Hero hero = entityManager.find(Hero.class, id);

// Update
hero.setPowerLevel(95);
entityManager.merge(hero);

// Delete
entityManager.remove(hero);

Métodos Avanzados

// Obtener referencia lazy
Hero hero = entityManager.getReference(Hero.class, id);

// Refrescar desde BD
entityManager.refresh(hero);

// Desvincular del contexto
entityManager.detach(hero);

// Verificar si está gestionada
boolean isManaged = entityManager.contains(hero);

// Forzar sincronización
entityManager.flush();

// Limpiar contexto
entityManager.clear();

Named Queries

Las Named Queries se definen en las entidades y se validan en tiempo de compilación:

@Entity
@NamedQueries({
    @NamedQuery(
        name = "Hero.findAll",
        query = "SELECT h FROM Hero h ORDER BY h.name"
    ),
    @NamedQuery(
        name = "Hero.findByPowerLevel",
        query = "SELECT h FROM Hero h WHERE h.powerLevel >= :minLevel"
    )
})
public class Hero {
    // ...
}

// Uso
TypedQuery<Hero> query = entityManager.createNamedQuery("Hero.findAll", Hero.class);
List<Hero> heroes = query.getResultList();

JPQL (Java Persistence Query Language)

JPQL permite escribir queries dinámicas usando sintaxis similar a SQL pero orientada a objetos:

String jpql = "SELECT h FROM Hero h WHERE h.powerLevel >= :minLevel";
TypedQuery<Hero> query = entityManager.createQuery(jpql, Hero.class);
query.setParameter("minLevel", 80);
List<Hero> heroes = query.getResultList();

JOIN FETCH (Evitar N+1)

String jpql = "SELECT DISTINCT h FROM Hero h LEFT JOIN FETCH h.missions";
TypedQuery<Hero> query = entityManager.createQuery(jpql, Hero.class);
List<Hero> heroes = query.getResultList();

Criteria API

La Criteria API permite construir queries type-safe programáticamente:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Hero> query = cb.createQuery(Hero.class);
Root<Hero> hero = query.from(Hero.class);

Predicate powerPredicate = cb.greaterThanOrEqualTo(hero.get("powerLevel"), 80);
query.where(powerPredicate);
query.orderBy(cb.desc(hero.get("powerLevel")));

TypedQuery<Hero> typedQuery = entityManager.createQuery(query);
List<Hero> heroes = typedQuery.getResultList();

Relaciones entre Entidades

OneToMany

@Entity
public class Hero {
    @OneToMany(mappedBy = "hero", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Mission> missions;
}

ManyToOne

@Entity
public class Mission {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "hero_id", nullable = false)
    private Hero hero;
}

Lifecycle Callbacks

Los callbacks permiten ejecutar código en diferentes momentos del ciclo de vida:

@Entity
public class Hero {
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }

    @PostLoad
    protected void onLoad() {
        // Inicializar colecciones lazy
    }
}

Optimistic Locking

El @Version permite implementar optimistic locking:

@Entity
public class Hero {
    @Version
    private Long version;
}

Ejemplo Completo

Nuestro demo muestra:

  • EntityManager con todas sus operaciones

  • Named Queries

  • JPQL queries dinámicas

  • Criteria API

  • Relaciones OneToMany/ManyToOne

  • Lifecycle callbacks

  • Optimistic locking

Ventajas en Quarkus

  1. Implementación Completa: Todas las características de JPA

  2. Integración CDI: EntityManager inyectable con @Inject

  3. Performance: Hibernate optimizado para Quarkus

  4. Startup Rápido: Procesamiento en tiempo de compilación

Conclusión

JPA en Quarkus proporciona acceso completo a bases de datos relacionales con todas las características de la especificación. La integración con CDI y Transactions hace que sea muy fácil de usar.

Recursos

More from this blog

JoeDayz

52 posts

Community Guy | Java Champion | AWS Architect | Software Architect