CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-jakarta-persistence--jakarta-persistence-api

Jakarta Persistence API provides a comprehensive framework for object-relational mapping, entity lifecycle management, and database operations in Java applications

Overview
Eval results
Files

queries.mddocs/

Query Execution

Complete reference for executing JPQL queries, native SQL queries, stored procedures, and named queries in Jakarta Persistence.

Imports

import jakarta.persistence.*;

Capabilities

Query Interface

Execute dynamic queries and control query execution.

/**
 * Base interface for executing queries
 * @since 1.0
 */
public interface Query {
    /**
     * Execute a SELECT query and return the query results as a List
     * @return list of results
     */
    List getResultList();

    /**
     * Execute a SELECT query that returns a single result
     * @return the result
     * @throws NoResultException if no result
     * @throws NonUniqueResultException if more than one result
     */
    Object getSingleResult();

    /**
     * Execute an UPDATE or DELETE statement
     * @return the number of entities updated or deleted
     */
    int executeUpdate();

    /**
     * Execute a SELECT query and return results as a Stream
     * @return a stream of the results
     * @since 2.2
     */
    Stream getResultStream();

    /**
     * Set the maximum number of results to retrieve
     * @param maxResult maximum number of results
     * @return the same query instance
     */
    Query setMaxResults(int maxResult);

    /**
     * Get the maximum number of results to retrieve
     * @return maximum number of results
     * @since 2.0
     */
    int getMaxResults();

    /**
     * Set the position of the first result to retrieve
     * @param startPosition position of first result (numbered from 0)
     * @return the same query instance
     */
    Query setFirstResult(int startPosition);

    /**
     * Get the position of the first result
     * @return position of first result
     * @since 2.0
     */
    int getFirstResult();

    /**
     * Set a query hint
     * @param hintName hint name
     * @param value hint value
     * @return the same query instance
     */
    Query setHint(String hintName, Object value);

    /**
     * Get the query hints
     * @return query hints
     * @since 2.0
     */
    Map<String, Object> getHints();

    /**
     * Bind a value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @return the same query instance
     */
    <T> Query setParameter(String name, T value);

    /**
     * Bind a value to a positional parameter
     * @param position parameter position (numbered from 1)
     * @param value parameter value
     * @return the same query instance
     */
    Query setParameter(int position, Object value);

    /**
     * Bind a Calendar value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    Query setParameter(String name, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    Query setParameter(String name, Date value, TemporalType temporalType);

    /**
     * Bind a Calendar value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    Query setParameter(int position, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    Query setParameter(int position, Date value, TemporalType temporalType);

    /**
     * Bind a Parameter object
     * @param param parameter object
     * @param value parameter value
     * @return the same query instance
     * @since 2.0
     */
    <T> Query setParameter(Parameter<T> param, T value);

    /**
     * Bind a Calendar Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     * @since 2.0
     */
    Query setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     * @since 2.0
     */
    Query setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

    /**
     * Get the parameters of the query
     * @return parameters
     * @since 2.0
     */
    Set<Parameter<?>> getParameters();

    /**
     * Get the parameter object for a named parameter
     * @param name parameter name
     * @return parameter object
     * @since 2.0
     */
    Parameter<?> getParameter(String name);

    /**
     * Get a typed parameter object for a named parameter
     * @param name parameter name
     * @param type parameter type
     * @return parameter object
     * @since 2.0
     */
    <T> Parameter<T> getParameter(String name, Class<T> type);

    /**
     * Get the parameter object for a positional parameter
     * @param position parameter position
     * @return parameter object
     * @since 2.0
     */
    Parameter<?> getParameter(int position);

    /**
     * Get a typed parameter object for a positional parameter
     * @param position parameter position
     * @param type parameter type
     * @return parameter object
     * @since 2.0
     */
    <T> Parameter<T> getParameter(int position, Class<T> type);

    /**
     * Check if a parameter has been bound
     * @param param parameter object
     * @return true if bound
     * @since 2.0
     */
    boolean isBound(Parameter<?> param);

    /**
     * Get the value bound to a parameter
     * @param param parameter object
     * @return parameter value
     * @since 2.0
     */
    <T> T getParameterValue(Parameter<T> param);

    /**
     * Get the value bound to a named parameter
     * @param name parameter name
     * @return parameter value
     * @since 2.0
     */
    Object getParameterValue(String name);

    /**
     * Get the value bound to a positional parameter
     * @param position parameter position
     * @return parameter value
     * @since 2.0
     */
    Object getParameterValue(int position);

    /**
     * Set the flush mode for the query
     * @param flushMode flush mode
     * @return the same query instance
     */
    Query setFlushMode(FlushModeType flushMode);

    /**
     * Get the flush mode for the query
     * @return flush mode
     * @since 2.0
     */
    FlushModeType getFlushMode();

    /**
     * Set the lock mode for the query
     * @param lockMode lock mode
     * @return the same query instance
     * @since 2.0
     */
    Query setLockMode(LockModeType lockMode);

    /**
     * Get the lock mode for the query
     * @return lock mode
     * @since 2.0
     */
    LockModeType getLockMode();

    /**
     * Return an object of the specified type to allow access to provider-specific API
     * @param cls the class of the object to be returned
     * @return an instance of the specified class
     * @since 2.0
     */
    <T> T unwrap(Class<T> cls);
}

/**
 * Parameter interface for query parameters
 * @since 2.0
 */
public interface Parameter<T> {
    /**
     * Get the parameter name, or null if not named
     * @return parameter name
     */
    String getName();

    /**
     * Get the parameter position, or null if named
     * @return parameter position
     */
    Integer getPosition();

    /**
     * Get the Java type of the parameter
     * @return parameter type
     */
    Class<T> getParameterType();
}

Usage Example:

EntityManager em = emf.createEntityManager();

// Simple query
Query query = em.createQuery("SELECT u FROM User u WHERE u.name = :name");
query.setParameter("name", "Alice");
query.setMaxResults(10);
query.setFirstResult(0);
List users = query.getResultList();

// Get single result
Query singleQuery = em.createQuery("SELECT u FROM User u WHERE u.id = :id");
singleQuery.setParameter("id", 1L);
Object user = singleQuery.getSingleResult();

// Update query
Query updateQuery = em.createQuery("UPDATE User u SET u.status = :status WHERE u.active = false");
updateQuery.setParameter("status", "INACTIVE");
int updated = updateQuery.executeUpdate();

// Stream results
try (Stream<User> stream = em.createQuery("SELECT u FROM User u", User.class).getResultStream()) {
    stream.forEach(u -> System.out.println(u.getName()));
}

// Query hints
query.setHint("jakarta.persistence.query.timeout", 5000);
query.setHint("jakarta.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);

// Temporal parameters
Query dateQuery = em.createQuery("SELECT o FROM Order o WHERE o.orderDate > :date");
dateQuery.setParameter("date", new Date(), TemporalType.DATE);

TypedQuery Interface

Execute type-safe queries with compile-time checking.

/**
 * Interface for executing typed queries
 * @since 2.0
 */
public interface TypedQuery<X> extends Query {
    /**
     * Execute a SELECT query and return the query results as a typed List
     * @return list of results
     */
    List<X> getResultList();

    /**
     * Execute a SELECT query that returns a single typed result
     * @return the result
     * @throws NoResultException if no result
     * @throws NonUniqueResultException if more than one result
     */
    X getSingleResult();

    /**
     * Execute a SELECT query and return results as a typed Stream
     * @return a stream of the results
     * @since 2.2
     */
    Stream<X> getResultStream();

    /**
     * Set the maximum number of results
     * @param maxResult maximum number of results
     * @return the same query instance
     */
    TypedQuery<X> setMaxResults(int maxResult);

    /**
     * Set the position of the first result
     * @param startPosition position of first result
     * @return the same query instance
     */
    TypedQuery<X> setFirstResult(int startPosition);

    /**
     * Set a query hint
     * @param hintName hint name
     * @param value hint value
     * @return the same query instance
     */
    TypedQuery<X> setHint(String hintName, Object value);

    /**
     * Bind a value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @return the same query instance
     */
    <T> TypedQuery<X> setParameter(String name, T value);

    /**
     * Bind a value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @return the same query instance
     */
    TypedQuery<X> setParameter(int position, Object value);

    /**
     * Bind a Calendar value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(String name, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(String name, Date value, TemporalType temporalType);

    /**
     * Bind a Calendar value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(int position, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(int position, Date value, TemporalType temporalType);

    /**
     * Bind a Parameter object
     * @param param parameter object
     * @param value parameter value
     * @return the same query instance
     */
    <T> TypedQuery<X> setParameter(Parameter<T> param, T value);

    /**
     * Bind a Calendar Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    TypedQuery<X> setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

    /**
     * Set the flush mode
     * @param flushMode flush mode
     * @return the same query instance
     */
    TypedQuery<X> setFlushMode(FlushModeType flushMode);

    /**
     * Set the lock mode
     * @param lockMode lock mode
     * @return the same query instance
     */
    TypedQuery<X> setLockMode(LockModeType lockMode);
}

Usage Example:

EntityManager em = emf.createEntityManager();

// Typed query
TypedQuery<User> query = em.createQuery(
    "SELECT u FROM User u WHERE u.email LIKE :pattern", User.class);
query.setParameter("pattern", "%@example.com");
List<User> users = query.getResultList();

// Single typed result
TypedQuery<User> singleQuery = em.createQuery(
    "SELECT u FROM User u WHERE u.username = :username", User.class);
singleQuery.setParameter("username", "admin");
User admin = singleQuery.getSingleResult();

// Typed stream
TypedQuery<Order> orderQuery = em.createQuery(
    "SELECT o FROM Order o WHERE o.orderDate >= :date", Order.class);
orderQuery.setParameter("date", LocalDate.now().minusDays(7));
try (Stream<Order> orders = orderQuery.getResultStream()) {
    orders.filter(o -> o.getTotal().compareTo(BigDecimal.valueOf(100)) > 0)
          .forEach(System.out::println);
}

StoredProcedureQuery Interface

Execute stored procedures.

/**
 * Interface for controlling stored procedure query execution
 * @since 2.1
 */
public interface StoredProcedureQuery extends Query {
    /**
     * Register a stored procedure parameter
     * @param position parameter position (numbered from 1)
     * @param type parameter type
     * @param mode parameter mode
     * @return the same query instance
     */
    StoredProcedureQuery registerStoredProcedureParameter(int position, Class type, ParameterMode mode);

    /**
     * Register a named stored procedure parameter
     * @param parameterName parameter name
     * @param type parameter type
     * @param mode parameter mode
     * @return the same query instance
     */
    StoredProcedureQuery registerStoredProcedureParameter(String parameterName, Class type, ParameterMode mode);

    /**
     * Set a hint for the query
     * @param hintName hint name
     * @param value hint value
     * @return the same query instance
     */
    StoredProcedureQuery setHint(String hintName, Object value);

    /**
     * Bind a value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @return the same query instance
     */
    <T> StoredProcedureQuery setParameter(String name, T value);

    /**
     * Bind a value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(int position, Object value);

    /**
     * Bind a Calendar value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(String name, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a named parameter
     * @param name parameter name
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(String name, Date value, TemporalType temporalType);

    /**
     * Bind a Calendar value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(int position, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date value to a positional parameter
     * @param position parameter position
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(int position, Date value, TemporalType temporalType);

    /**
     * Bind a Parameter object
     * @param param parameter object
     * @param value parameter value
     * @return the same query instance
     */
    <T> StoredProcedureQuery setParameter(Parameter<T> param, T value);

    /**
     * Bind a Calendar Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

    /**
     * Bind a Date Parameter
     * @param param parameter object
     * @param value parameter value
     * @param temporalType temporal type
     * @return the same query instance
     */
    StoredProcedureQuery setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

    /**
     * Set the flush mode
     * @param flushMode flush mode
     * @return the same query instance
     */
    StoredProcedureQuery setFlushMode(FlushModeType flushMode);

    /**
     * Execute the stored procedure
     * @return true if the first result is a result set
     */
    boolean execute();

    /**
     * Get the update count or -1 if not applicable
     * @return update count
     */
    int getUpdateCount();

    /**
     * Check if there are more results available
     * @return true if more results are available
     */
    boolean hasMoreResults();

    /**
     * Get the output parameter value by position
     * @param position parameter position
     * @return output parameter value
     */
    Object getOutputParameterValue(int position);

    /**
     * Get the output parameter value by name
     * @param parameterName parameter name
     * @return output parameter value
     */
    Object getOutputParameterValue(String parameterName);
}

Usage Example:

EntityManager em = emf.createEntityManager();

// Create stored procedure query
StoredProcedureQuery query = em.createStoredProcedureQuery("calculate_bonus");

// Register parameters
query.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);
query.registerStoredProcedureParameter(2, BigDecimal.class, ParameterMode.OUT);
query.registerStoredProcedureParameter("result", String.class, ParameterMode.OUT);

// Set input parameters
query.setParameter(1, 12345L);

// Execute
query.execute();

// Get output parameters
BigDecimal bonus = (BigDecimal) query.getOutputParameterValue(2);
String result = (String) query.getOutputParameterValue("result");

// With result sets
StoredProcedureQuery spQuery = em.createStoredProcedureQuery("get_employees", Employee.class);
boolean hasResults = spQuery.execute();
if (hasResults) {
    List<Employee> employees = spQuery.getResultList();
}

Named Queries

Define static, reusable queries.

/**
 * Specifies a named JPQL query
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
@Repeatable(NamedQueries.class)
public @interface NamedQuery {
    /** (Required) The name of the query */
    String name();

    /** (Required) The JPQL query string */
    String query();

    /** (Optional) The lock mode type */
    LockModeType lockMode() default LockModeType.NONE;

    /** (Optional) Query hints */
    QueryHint[] hints() default {};
}

/**
 * Groups NamedQuery annotations
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface NamedQueries {
    /** Array of named queries */
    NamedQuery[] value();
}

/**
 * Specifies a named native SQL query
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
@Repeatable(NamedNativeQueries.class)
public @interface NamedNativeQuery {
    /** (Required) The name of the query */
    String name();

    /** (Required) The SQL query string */
    String query();

    /** (Optional) Query hints */
    QueryHint[] hints() default {};

    /** (Optional) The class of the result */
    Class resultClass() default void.class;

    /** (Optional) The name of the SQL result set mapping */
    String resultSetMapping() default "";
}

/**
 * Groups NamedNativeQuery annotations
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface NamedNativeQueries {
    /** Array of named native queries */
    NamedNativeQuery[] value();
}

/**
 * Specifies a query hint
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface QueryHint {
    /** (Required) The name of the hint */
    String name();

    /** (Required) The value of the hint */
    String value();
}

/**
 * Specifies a named stored procedure query
 * @since 2.1
 */
@Target({TYPE})
@Retention(RUNTIME)
@Repeatable(NamedStoredProcedureQueries.class)
public @interface NamedStoredProcedureQuery {
    /** (Required) The name of the query */
    String name();

    /** (Required) The name of the stored procedure */
    String procedureName();

    /** (Optional) Information about stored procedure parameters */
    StoredProcedureParameter[] parameters() default {};

    /** (Optional) The class of the result */
    Class[] resultClasses() default {};

    /** (Optional) The names of SQL result set mappings */
    String[] resultSetMappings() default {};

    /** (Optional) Query hints */
    QueryHint[] hints() default {};
}

/**
 * Groups NamedStoredProcedureQuery annotations
 * @since 2.1
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface NamedStoredProcedureQueries {
    /** Array of named stored procedure queries */
    NamedStoredProcedureQuery[] value();
}

/**
 * Specifies a parameter of a named stored procedure query
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface StoredProcedureParameter {
    /** (Optional) The name of the parameter */
    String name() default "";

    /** (Optional) The parameter mode */
    ParameterMode mode() default ParameterMode.IN;

    /** (Required) The type of the parameter */
    Class type();
}

Usage Example:

@Entity
@NamedQueries({
    @NamedQuery(
        name = "User.findAll",
        query = "SELECT u FROM User u ORDER BY u.name"
    ),
    @NamedQuery(
        name = "User.findByEmail",
        query = "SELECT u FROM User u WHERE u.email = :email",
        hints = {
            @QueryHint(name = "jakarta.persistence.cache.retrieveMode", value = "USE")
        }
    ),
    @NamedQuery(
        name = "User.findActiveWithOrders",
        query = "SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.orders WHERE u.active = true"
    )
})
@NamedNativeQueries({
    @NamedNativeQuery(
        name = "User.findByNativeSQL",
        query = "SELECT * FROM users WHERE name LIKE ?",
        resultClass = User.class
    )
})
@NamedStoredProcedureQueries({
    @NamedStoredProcedureQuery(
        name = "User.calculateDiscount",
        procedureName = "sp_calculate_user_discount",
        parameters = {
            @StoredProcedureParameter(name = "userId", type = Long.class, mode = ParameterMode.IN),
            @StoredProcedureParameter(name = "discount", type = BigDecimal.class, mode = ParameterMode.OUT)
        }
    )
})
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
    private boolean active;

    @OneToMany(mappedBy = "user")
    private List<Order> orders;
}

// Using named queries
TypedQuery<User> query = em.createNamedQuery("User.findByEmail", User.class);
query.setParameter("email", "alice@example.com");
User user = query.getSingleResult();

Query nativeQuery = em.createNamedQuery("User.findByNativeSQL");
nativeQuery.setParameter(1, "A%");
List<User> users = nativeQuery.getResultList();

StoredProcedureQuery spQuery = em.createNamedStoredProcedureQuery("User.calculateDiscount");
spQuery.setParameter("userId", 1L);
spQuery.execute();
BigDecimal discount = (BigDecimal) spQuery.getOutputParameterValue("discount");

SQL Result Set Mapping

Map native SQL query results to entities or custom result types.

/**
 * Specifies the mapping of the result of a native SQL query or stored procedure
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
@Repeatable(SqlResultSetMappings.class)
public @interface SqlResultSetMapping {
    /** (Required) The name of the result set mapping */
    String name();

    /** (Optional) Entities to map to */
    EntityResult[] entities() default {};

    /** (Optional) Constructor results */
    ConstructorResult[] classes() default {};

    /** (Optional) Column results */
    ColumnResult[] columns() default {};
}

/**
 * Groups SqlResultSetMapping annotations
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface SqlResultSetMappings {
    /** Array of result set mappings */
    SqlResultSetMapping[] value();
}

/**
 * Used to map a SQL result to an entity
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface EntityResult {
    /** (Required) The class of the entity */
    Class entityClass();

    /** (Optional) Field mappings */
    FieldResult[] fields() default {};

    /** (Optional) The name of the discriminator column */
    String discriminatorColumn() default "";
}

/**
 * Used to map columns to entity fields
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface FieldResult {
    /** (Required) Name of the persistent field or property */
    String name();

    /** (Required) Name of the column in the SELECT list */
    String column();
}

/**
 * Used to map SQL query results to a constructor
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface ConstructorResult {
    /** (Required) The class whose constructor is to be invoked */
    Class targetClass();

    /** (Required) The columns to be passed to the constructor */
    ColumnResult[] columns();
}

/**
 * Used to map a column in the SELECT list to a constructor parameter or scalar result
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface ColumnResult {
    /** (Required) The name of the column in the SELECT list */
    String name();

    /** (Optional) The Java type of the column */
    Class type() default void.class;
}

Usage Example:

@Entity
@SqlResultSetMappings({
    @SqlResultSetMapping(
        name = "UserOrderMapping",
        entities = {
            @EntityResult(
                entityClass = User.class,
                fields = {
                    @FieldResult(name = "id", column = "user_id"),
                    @FieldResult(name = "name", column = "user_name")
                }
            ),
            @EntityResult(
                entityClass = Order.class,
                fields = {
                    @FieldResult(name = "id", column = "order_id"),
                    @FieldResult(name = "orderDate", column = "order_date")
                }
            )
        }
    ),
    @SqlResultSetMapping(
        name = "UserSummaryMapping",
        classes = {
            @ConstructorResult(
                targetClass = UserSummary.class,
                columns = {
                    @ColumnResult(name = "user_id", type = Long.class),
                    @ColumnResult(name = "user_name", type = String.class),
                    @ColumnResult(name = "order_count", type = Long.class)
                }
            )
        }
    ),
    @SqlResultSetMapping(
        name = "ScalarMapping",
        columns = {
            @ColumnResult(name = "total", type = BigDecimal.class),
            @ColumnResult(name = "count", type = Long.class)
        }
    )
})
public class User {
    @Id
    private Long id;
    private String name;
}

// Using result set mapping
Query query = em.createNativeQuery(
    "SELECT u.id as user_id, u.name as user_name, o.id as order_id, o.order_date " +
    "FROM users u JOIN orders o ON u.id = o.user_id",
    "UserOrderMapping"
);
List results = query.getResultList();

// Constructor result mapping
Query summaryQuery = em.createNativeQuery(
    "SELECT u.id as user_id, u.name as user_name, COUNT(o.id) as order_count " +
    "FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name",
    "UserSummaryMapping"
);
List<UserSummary> summaries = summaryQuery.getResultList();

// Scalar result mapping
Query scalarQuery = em.createNativeQuery(
    "SELECT SUM(amount) as total, COUNT(*) as count FROM orders",
    "ScalarMapping"
);
Object[] result = (Object[]) scalarQuery.getSingleResult();
BigDecimal total = (BigDecimal) result[0];
Long count = (Long) result[1];

Tuple Results

Work with multi-column query results.

/**
 * Interface for extracting values from Tuple results
 * @since 2.0
 */
public interface Tuple {
    /**
     * Get the value of the specified element
     * @param tupleElement tuple element
     * @return value
     */
    <X> X get(TupleElement<X> tupleElement);

    /**
     * Get the value at the specified position
     * @param i position (numbered from 0)
     * @param type the type of the result
     * @return value
     */
    <X> X get(int i, Class<X> type);

    /**
     * Get the value at the specified position
     * @param i position (numbered from 0)
     * @return value
     */
    Object get(int i);

    /**
     * Get the value by alias
     * @param alias alias name
     * @param type the type of the result
     * @return value
     */
    <X> X get(String alias, Class<X> type);

    /**
     * Get the value by alias
     * @param alias alias name
     * @return value
     */
    Object get(String alias);

    /**
     * Return the values of the tuple as an array
     * @return array of values
     */
    Object[] toArray();

    /**
     * Return the tuple elements
     * @return tuple elements
     */
    List<TupleElement<?>> getElements();
}

/**
 * Represents a tuple element
 * @since 2.0
 */
public interface TupleElement<X> {
    /**
     * Return the Java type of the element
     * @return Java type
     */
    Class<? extends X> getJavaType();

    /**
     * Return the alias of the element
     * @return alias
     */
    String getAlias();
}

Usage Example:

EntityManager em = emf.createEntityManager();

// Tuple query
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<User> user = cq.from(User.class);
cq.multiselect(
    user.get("id").alias("userId"),
    user.get("name").alias("userName"),
    cb.count(user.get("orders")).alias("orderCount")
);
cq.groupBy(user.get("id"), user.get("name"));

TypedQuery<Tuple> query = em.createQuery(cq);
List<Tuple> results = query.getResultList();

for (Tuple tuple : results) {
    Long id = tuple.get("userId", Long.class);
    String name = tuple.get("userName", String.class);
    Long count = tuple.get("orderCount", Long.class);
    System.out.println(name + " has " + count + " orders");
}

Install with Tessl CLI

npx tessl i tessl/maven-jakarta-persistence--jakarta-persistence-api

docs

caching-locking.md

criteria-api.md

entity-manager.md

entity-mapping.md

index.md

lifecycle-callbacks.md

metamodel.md

queries.md

spi.md

tile.json