Jakarta Persistence API provides a comprehensive framework for object-relational mapping, entity lifecycle management, and database operations in Java applications
Complete reference for executing JPQL queries, native SQL queries, stored procedures, and named queries in Jakarta Persistence.
import jakarta.persistence.*;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);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);
}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();
}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");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];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