or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching-locking.mdcriteria-api.mdentity-manager.mdentity-mapping.mdindex.mdlifecycle-callbacks.mdmetamodel.mdqueries.mdspi.md

queries.mddocs/

0

# Query Execution

1

2

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

3

4

## Imports

5

6

```java { .api }

7

import jakarta.persistence.*;

8

```

9

10

## Capabilities

11

12

### Query Interface

13

14

Execute dynamic queries and control query execution.

15

16

```java { .api }

17

/**

18

* Base interface for executing queries

19

* @since 1.0

20

*/

21

public interface Query {

22

/**

23

* Execute a SELECT query and return the query results as a List

24

* @return list of results

25

*/

26

List getResultList();

27

28

/**

29

* Execute a SELECT query that returns a single result

30

* @return the result

31

* @throws NoResultException if no result

32

* @throws NonUniqueResultException if more than one result

33

*/

34

Object getSingleResult();

35

36

/**

37

* Execute an UPDATE or DELETE statement

38

* @return the number of entities updated or deleted

39

*/

40

int executeUpdate();

41

42

/**

43

* Execute a SELECT query and return results as a Stream

44

* @return a stream of the results

45

* @since 2.2

46

*/

47

Stream getResultStream();

48

49

/**

50

* Set the maximum number of results to retrieve

51

* @param maxResult maximum number of results

52

* @return the same query instance

53

*/

54

Query setMaxResults(int maxResult);

55

56

/**

57

* Get the maximum number of results to retrieve

58

* @return maximum number of results

59

* @since 2.0

60

*/

61

int getMaxResults();

62

63

/**

64

* Set the position of the first result to retrieve

65

* @param startPosition position of first result (numbered from 0)

66

* @return the same query instance

67

*/

68

Query setFirstResult(int startPosition);

69

70

/**

71

* Get the position of the first result

72

* @return position of first result

73

* @since 2.0

74

*/

75

int getFirstResult();

76

77

/**

78

* Set a query hint

79

* @param hintName hint name

80

* @param value hint value

81

* @return the same query instance

82

*/

83

Query setHint(String hintName, Object value);

84

85

/**

86

* Get the query hints

87

* @return query hints

88

* @since 2.0

89

*/

90

Map<String, Object> getHints();

91

92

/**

93

* Bind a value to a named parameter

94

* @param name parameter name

95

* @param value parameter value

96

* @return the same query instance

97

*/

98

<T> Query setParameter(String name, T value);

99

100

/**

101

* Bind a value to a positional parameter

102

* @param position parameter position (numbered from 1)

103

* @param value parameter value

104

* @return the same query instance

105

*/

106

Query setParameter(int position, Object value);

107

108

/**

109

* Bind a Calendar value to a named parameter

110

* @param name parameter name

111

* @param value parameter value

112

* @param temporalType temporal type

113

* @return the same query instance

114

*/

115

Query setParameter(String name, Calendar value, TemporalType temporalType);

116

117

/**

118

* Bind a Date value to a named parameter

119

* @param name parameter name

120

* @param value parameter value

121

* @param temporalType temporal type

122

* @return the same query instance

123

*/

124

Query setParameter(String name, Date value, TemporalType temporalType);

125

126

/**

127

* Bind a Calendar value to a positional parameter

128

* @param position parameter position

129

* @param value parameter value

130

* @param temporalType temporal type

131

* @return the same query instance

132

*/

133

Query setParameter(int position, Calendar value, TemporalType temporalType);

134

135

/**

136

* Bind a Date value to a positional parameter

137

* @param position parameter position

138

* @param value parameter value

139

* @param temporalType temporal type

140

* @return the same query instance

141

*/

142

Query setParameter(int position, Date value, TemporalType temporalType);

143

144

/**

145

* Bind a Parameter object

146

* @param param parameter object

147

* @param value parameter value

148

* @return the same query instance

149

* @since 2.0

150

*/

151

<T> Query setParameter(Parameter<T> param, T value);

152

153

/**

154

* Bind a Calendar Parameter

155

* @param param parameter object

156

* @param value parameter value

157

* @param temporalType temporal type

158

* @return the same query instance

159

* @since 2.0

160

*/

161

Query setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

162

163

/**

164

* Bind a Date Parameter

165

* @param param parameter object

166

* @param value parameter value

167

* @param temporalType temporal type

168

* @return the same query instance

169

* @since 2.0

170

*/

171

Query setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

172

173

/**

174

* Get the parameters of the query

175

* @return parameters

176

* @since 2.0

177

*/

178

Set<Parameter<?>> getParameters();

179

180

/**

181

* Get the parameter object for a named parameter

182

* @param name parameter name

183

* @return parameter object

184

* @since 2.0

185

*/

186

Parameter<?> getParameter(String name);

187

188

/**

189

* Get a typed parameter object for a named parameter

190

* @param name parameter name

191

* @param type parameter type

192

* @return parameter object

193

* @since 2.0

194

*/

195

<T> Parameter<T> getParameter(String name, Class<T> type);

196

197

/**

198

* Get the parameter object for a positional parameter

199

* @param position parameter position

200

* @return parameter object

201

* @since 2.0

202

*/

203

Parameter<?> getParameter(int position);

204

205

/**

206

* Get a typed parameter object for a positional parameter

207

* @param position parameter position

208

* @param type parameter type

209

* @return parameter object

210

* @since 2.0

211

*/

212

<T> Parameter<T> getParameter(int position, Class<T> type);

213

214

/**

215

* Check if a parameter has been bound

216

* @param param parameter object

217

* @return true if bound

218

* @since 2.0

219

*/

220

boolean isBound(Parameter<?> param);

221

222

/**

223

* Get the value bound to a parameter

224

* @param param parameter object

225

* @return parameter value

226

* @since 2.0

227

*/

228

<T> T getParameterValue(Parameter<T> param);

229

230

/**

231

* Get the value bound to a named parameter

232

* @param name parameter name

233

* @return parameter value

234

* @since 2.0

235

*/

236

Object getParameterValue(String name);

237

238

/**

239

* Get the value bound to a positional parameter

240

* @param position parameter position

241

* @return parameter value

242

* @since 2.0

243

*/

244

Object getParameterValue(int position);

245

246

/**

247

* Set the flush mode for the query

248

* @param flushMode flush mode

249

* @return the same query instance

250

*/

251

Query setFlushMode(FlushModeType flushMode);

252

253

/**

254

* Get the flush mode for the query

255

* @return flush mode

256

* @since 2.0

257

*/

258

FlushModeType getFlushMode();

259

260

/**

261

* Set the lock mode for the query

262

* @param lockMode lock mode

263

* @return the same query instance

264

* @since 2.0

265

*/

266

Query setLockMode(LockModeType lockMode);

267

268

/**

269

* Get the lock mode for the query

270

* @return lock mode

271

* @since 2.0

272

*/

273

LockModeType getLockMode();

274

275

/**

276

* Return an object of the specified type to allow access to provider-specific API

277

* @param cls the class of the object to be returned

278

* @return an instance of the specified class

279

* @since 2.0

280

*/

281

<T> T unwrap(Class<T> cls);

282

}

283

284

/**

285

* Parameter interface for query parameters

286

* @since 2.0

287

*/

288

public interface Parameter<T> {

289

/**

290

* Get the parameter name, or null if not named

291

* @return parameter name

292

*/

293

String getName();

294

295

/**

296

* Get the parameter position, or null if named

297

* @return parameter position

298

*/

299

Integer getPosition();

300

301

/**

302

* Get the Java type of the parameter

303

* @return parameter type

304

*/

305

Class<T> getParameterType();

306

}

307

```

308

309

**Usage Example:**

310

311

```java

312

EntityManager em = emf.createEntityManager();

313

314

// Simple query

315

Query query = em.createQuery("SELECT u FROM User u WHERE u.name = :name");

316

query.setParameter("name", "Alice");

317

query.setMaxResults(10);

318

query.setFirstResult(0);

319

List users = query.getResultList();

320

321

// Get single result

322

Query singleQuery = em.createQuery("SELECT u FROM User u WHERE u.id = :id");

323

singleQuery.setParameter("id", 1L);

324

Object user = singleQuery.getSingleResult();

325

326

// Update query

327

Query updateQuery = em.createQuery("UPDATE User u SET u.status = :status WHERE u.active = false");

328

updateQuery.setParameter("status", "INACTIVE");

329

int updated = updateQuery.executeUpdate();

330

331

// Stream results

332

try (Stream<User> stream = em.createQuery("SELECT u FROM User u", User.class).getResultStream()) {

333

stream.forEach(u -> System.out.println(u.getName()));

334

}

335

336

// Query hints

337

query.setHint("jakarta.persistence.query.timeout", 5000);

338

query.setHint("jakarta.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);

339

340

// Temporal parameters

341

Query dateQuery = em.createQuery("SELECT o FROM Order o WHERE o.orderDate > :date");

342

dateQuery.setParameter("date", new Date(), TemporalType.DATE);

343

```

344

345

### TypedQuery Interface

346

347

Execute type-safe queries with compile-time checking.

348

349

```java { .api }

350

/**

351

* Interface for executing typed queries

352

* @since 2.0

353

*/

354

public interface TypedQuery<X> extends Query {

355

/**

356

* Execute a SELECT query and return the query results as a typed List

357

* @return list of results

358

*/

359

List<X> getResultList();

360

361

/**

362

* Execute a SELECT query that returns a single typed result

363

* @return the result

364

* @throws NoResultException if no result

365

* @throws NonUniqueResultException if more than one result

366

*/

367

X getSingleResult();

368

369

/**

370

* Execute a SELECT query and return results as a typed Stream

371

* @return a stream of the results

372

* @since 2.2

373

*/

374

Stream<X> getResultStream();

375

376

/**

377

* Set the maximum number of results

378

* @param maxResult maximum number of results

379

* @return the same query instance

380

*/

381

TypedQuery<X> setMaxResults(int maxResult);

382

383

/**

384

* Set the position of the first result

385

* @param startPosition position of first result

386

* @return the same query instance

387

*/

388

TypedQuery<X> setFirstResult(int startPosition);

389

390

/**

391

* Set a query hint

392

* @param hintName hint name

393

* @param value hint value

394

* @return the same query instance

395

*/

396

TypedQuery<X> setHint(String hintName, Object value);

397

398

/**

399

* Bind a value to a named parameter

400

* @param name parameter name

401

* @param value parameter value

402

* @return the same query instance

403

*/

404

<T> TypedQuery<X> setParameter(String name, T value);

405

406

/**

407

* Bind a value to a positional parameter

408

* @param position parameter position

409

* @param value parameter value

410

* @return the same query instance

411

*/

412

TypedQuery<X> setParameter(int position, Object value);

413

414

/**

415

* Bind a Calendar value to a named parameter

416

* @param name parameter name

417

* @param value parameter value

418

* @param temporalType temporal type

419

* @return the same query instance

420

*/

421

TypedQuery<X> setParameter(String name, Calendar value, TemporalType temporalType);

422

423

/**

424

* Bind a Date value to a named parameter

425

* @param name parameter name

426

* @param value parameter value

427

* @param temporalType temporal type

428

* @return the same query instance

429

*/

430

TypedQuery<X> setParameter(String name, Date value, TemporalType temporalType);

431

432

/**

433

* Bind a Calendar value to a positional parameter

434

* @param position parameter position

435

* @param value parameter value

436

* @param temporalType temporal type

437

* @return the same query instance

438

*/

439

TypedQuery<X> setParameter(int position, Calendar value, TemporalType temporalType);

440

441

/**

442

* Bind a Date value to a positional parameter

443

* @param position parameter position

444

* @param value parameter value

445

* @param temporalType temporal type

446

* @return the same query instance

447

*/

448

TypedQuery<X> setParameter(int position, Date value, TemporalType temporalType);

449

450

/**

451

* Bind a Parameter object

452

* @param param parameter object

453

* @param value parameter value

454

* @return the same query instance

455

*/

456

<T> TypedQuery<X> setParameter(Parameter<T> param, T value);

457

458

/**

459

* Bind a Calendar Parameter

460

* @param param parameter object

461

* @param value parameter value

462

* @param temporalType temporal type

463

* @return the same query instance

464

*/

465

TypedQuery<X> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

466

467

/**

468

* Bind a Date Parameter

469

* @param param parameter object

470

* @param value parameter value

471

* @param temporalType temporal type

472

* @return the same query instance

473

*/

474

TypedQuery<X> setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

475

476

/**

477

* Set the flush mode

478

* @param flushMode flush mode

479

* @return the same query instance

480

*/

481

TypedQuery<X> setFlushMode(FlushModeType flushMode);

482

483

/**

484

* Set the lock mode

485

* @param lockMode lock mode

486

* @return the same query instance

487

*/

488

TypedQuery<X> setLockMode(LockModeType lockMode);

489

}

490

```

491

492

**Usage Example:**

493

494

```java

495

EntityManager em = emf.createEntityManager();

496

497

// Typed query

498

TypedQuery<User> query = em.createQuery(

499

"SELECT u FROM User u WHERE u.email LIKE :pattern", User.class);

500

query.setParameter("pattern", "%@example.com");

501

List<User> users = query.getResultList();

502

503

// Single typed result

504

TypedQuery<User> singleQuery = em.createQuery(

505

"SELECT u FROM User u WHERE u.username = :username", User.class);

506

singleQuery.setParameter("username", "admin");

507

User admin = singleQuery.getSingleResult();

508

509

// Typed stream

510

TypedQuery<Order> orderQuery = em.createQuery(

511

"SELECT o FROM Order o WHERE o.orderDate >= :date", Order.class);

512

orderQuery.setParameter("date", LocalDate.now().minusDays(7));

513

try (Stream<Order> orders = orderQuery.getResultStream()) {

514

orders.filter(o -> o.getTotal().compareTo(BigDecimal.valueOf(100)) > 0)

515

.forEach(System.out::println);

516

}

517

```

518

519

### StoredProcedureQuery Interface

520

521

Execute stored procedures.

522

523

```java { .api }

524

/**

525

* Interface for controlling stored procedure query execution

526

* @since 2.1

527

*/

528

public interface StoredProcedureQuery extends Query {

529

/**

530

* Register a stored procedure parameter

531

* @param position parameter position (numbered from 1)

532

* @param type parameter type

533

* @param mode parameter mode

534

* @return the same query instance

535

*/

536

StoredProcedureQuery registerStoredProcedureParameter(int position, Class type, ParameterMode mode);

537

538

/**

539

* Register a named stored procedure parameter

540

* @param parameterName parameter name

541

* @param type parameter type

542

* @param mode parameter mode

543

* @return the same query instance

544

*/

545

StoredProcedureQuery registerStoredProcedureParameter(String parameterName, Class type, ParameterMode mode);

546

547

/**

548

* Set a hint for the query

549

* @param hintName hint name

550

* @param value hint value

551

* @return the same query instance

552

*/

553

StoredProcedureQuery setHint(String hintName, Object value);

554

555

/**

556

* Bind a value to a named parameter

557

* @param name parameter name

558

* @param value parameter value

559

* @return the same query instance

560

*/

561

<T> StoredProcedureQuery setParameter(String name, T value);

562

563

/**

564

* Bind a value to a positional parameter

565

* @param position parameter position

566

* @param value parameter value

567

* @return the same query instance

568

*/

569

StoredProcedureQuery setParameter(int position, Object value);

570

571

/**

572

* Bind a Calendar value to a named parameter

573

* @param name parameter name

574

* @param value parameter value

575

* @param temporalType temporal type

576

* @return the same query instance

577

*/

578

StoredProcedureQuery setParameter(String name, Calendar value, TemporalType temporalType);

579

580

/**

581

* Bind a Date value to a named parameter

582

* @param name parameter name

583

* @param value parameter value

584

* @param temporalType temporal type

585

* @return the same query instance

586

*/

587

StoredProcedureQuery setParameter(String name, Date value, TemporalType temporalType);

588

589

/**

590

* Bind a Calendar value to a positional parameter

591

* @param position parameter position

592

* @param value parameter value

593

* @param temporalType temporal type

594

* @return the same query instance

595

*/

596

StoredProcedureQuery setParameter(int position, Calendar value, TemporalType temporalType);

597

598

/**

599

* Bind a Date value to a positional parameter

600

* @param position parameter position

601

* @param value parameter value

602

* @param temporalType temporal type

603

* @return the same query instance

604

*/

605

StoredProcedureQuery setParameter(int position, Date value, TemporalType temporalType);

606

607

/**

608

* Bind a Parameter object

609

* @param param parameter object

610

* @param value parameter value

611

* @return the same query instance

612

*/

613

<T> StoredProcedureQuery setParameter(Parameter<T> param, T value);

614

615

/**

616

* Bind a Calendar Parameter

617

* @param param parameter object

618

* @param value parameter value

619

* @param temporalType temporal type

620

* @return the same query instance

621

*/

622

StoredProcedureQuery setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);

623

624

/**

625

* Bind a Date Parameter

626

* @param param parameter object

627

* @param value parameter value

628

* @param temporalType temporal type

629

* @return the same query instance

630

*/

631

StoredProcedureQuery setParameter(Parameter<Date> param, Date value, TemporalType temporalType);

632

633

/**

634

* Set the flush mode

635

* @param flushMode flush mode

636

* @return the same query instance

637

*/

638

StoredProcedureQuery setFlushMode(FlushModeType flushMode);

639

640

/**

641

* Execute the stored procedure

642

* @return true if the first result is a result set

643

*/

644

boolean execute();

645

646

/**

647

* Get the update count or -1 if not applicable

648

* @return update count

649

*/

650

int getUpdateCount();

651

652

/**

653

* Check if there are more results available

654

* @return true if more results are available

655

*/

656

boolean hasMoreResults();

657

658

/**

659

* Get the output parameter value by position

660

* @param position parameter position

661

* @return output parameter value

662

*/

663

Object getOutputParameterValue(int position);

664

665

/**

666

* Get the output parameter value by name

667

* @param parameterName parameter name

668

* @return output parameter value

669

*/

670

Object getOutputParameterValue(String parameterName);

671

}

672

```

673

674

**Usage Example:**

675

676

```java

677

EntityManager em = emf.createEntityManager();

678

679

// Create stored procedure query

680

StoredProcedureQuery query = em.createStoredProcedureQuery("calculate_bonus");

681

682

// Register parameters

683

query.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);

684

query.registerStoredProcedureParameter(2, BigDecimal.class, ParameterMode.OUT);

685

query.registerStoredProcedureParameter("result", String.class, ParameterMode.OUT);

686

687

// Set input parameters

688

query.setParameter(1, 12345L);

689

690

// Execute

691

query.execute();

692

693

// Get output parameters

694

BigDecimal bonus = (BigDecimal) query.getOutputParameterValue(2);

695

String result = (String) query.getOutputParameterValue("result");

696

697

// With result sets

698

StoredProcedureQuery spQuery = em.createStoredProcedureQuery("get_employees", Employee.class);

699

boolean hasResults = spQuery.execute();

700

if (hasResults) {

701

List<Employee> employees = spQuery.getResultList();

702

}

703

```

704

705

### Named Queries

706

707

Define static, reusable queries.

708

709

```java { .api }

710

/**

711

* Specifies a named JPQL query

712

* @since 1.0

713

*/

714

@Target({TYPE})

715

@Retention(RUNTIME)

716

@Repeatable(NamedQueries.class)

717

public @interface NamedQuery {

718

/** (Required) The name of the query */

719

String name();

720

721

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

722

String query();

723

724

/** (Optional) The lock mode type */

725

LockModeType lockMode() default LockModeType.NONE;

726

727

/** (Optional) Query hints */

728

QueryHint[] hints() default {};

729

}

730

731

/**

732

* Groups NamedQuery annotations

733

* @since 1.0

734

*/

735

@Target({TYPE})

736

@Retention(RUNTIME)

737

public @interface NamedQueries {

738

/** Array of named queries */

739

NamedQuery[] value();

740

}

741

742

/**

743

* Specifies a named native SQL query

744

* @since 1.0

745

*/

746

@Target({TYPE})

747

@Retention(RUNTIME)

748

@Repeatable(NamedNativeQueries.class)

749

public @interface NamedNativeQuery {

750

/** (Required) The name of the query */

751

String name();

752

753

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

754

String query();

755

756

/** (Optional) Query hints */

757

QueryHint[] hints() default {};

758

759

/** (Optional) The class of the result */

760

Class resultClass() default void.class;

761

762

/** (Optional) The name of the SQL result set mapping */

763

String resultSetMapping() default "";

764

}

765

766

/**

767

* Groups NamedNativeQuery annotations

768

* @since 1.0

769

*/

770

@Target({TYPE})

771

@Retention(RUNTIME)

772

public @interface NamedNativeQueries {

773

/** Array of named native queries */

774

NamedNativeQuery[] value();

775

}

776

777

/**

778

* Specifies a query hint

779

* @since 1.0

780

*/

781

@Target({})

782

@Retention(RUNTIME)

783

public @interface QueryHint {

784

/** (Required) The name of the hint */

785

String name();

786

787

/** (Required) The value of the hint */

788

String value();

789

}

790

791

/**

792

* Specifies a named stored procedure query

793

* @since 2.1

794

*/

795

@Target({TYPE})

796

@Retention(RUNTIME)

797

@Repeatable(NamedStoredProcedureQueries.class)

798

public @interface NamedStoredProcedureQuery {

799

/** (Required) The name of the query */

800

String name();

801

802

/** (Required) The name of the stored procedure */

803

String procedureName();

804

805

/** (Optional) Information about stored procedure parameters */

806

StoredProcedureParameter[] parameters() default {};

807

808

/** (Optional) The class of the result */

809

Class[] resultClasses() default {};

810

811

/** (Optional) The names of SQL result set mappings */

812

String[] resultSetMappings() default {};

813

814

/** (Optional) Query hints */

815

QueryHint[] hints() default {};

816

}

817

818

/**

819

* Groups NamedStoredProcedureQuery annotations

820

* @since 2.1

821

*/

822

@Target({TYPE})

823

@Retention(RUNTIME)

824

public @interface NamedStoredProcedureQueries {

825

/** Array of named stored procedure queries */

826

NamedStoredProcedureQuery[] value();

827

}

828

829

/**

830

* Specifies a parameter of a named stored procedure query

831

* @since 2.1

832

*/

833

@Target({})

834

@Retention(RUNTIME)

835

public @interface StoredProcedureParameter {

836

/** (Optional) The name of the parameter */

837

String name() default "";

838

839

/** (Optional) The parameter mode */

840

ParameterMode mode() default ParameterMode.IN;

841

842

/** (Required) The type of the parameter */

843

Class type();

844

}

845

```

846

847

**Usage Example:**

848

849

```java

850

@Entity

851

@NamedQueries({

852

@NamedQuery(

853

name = "User.findAll",

854

query = "SELECT u FROM User u ORDER BY u.name"

855

),

856

@NamedQuery(

857

name = "User.findByEmail",

858

query = "SELECT u FROM User u WHERE u.email = :email",

859

hints = {

860

@QueryHint(name = "jakarta.persistence.cache.retrieveMode", value = "USE")

861

}

862

),

863

@NamedQuery(

864

name = "User.findActiveWithOrders",

865

query = "SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.orders WHERE u.active = true"

866

)

867

})

868

@NamedNativeQueries({

869

@NamedNativeQuery(

870

name = "User.findByNativeSQL",

871

query = "SELECT * FROM users WHERE name LIKE ?",

872

resultClass = User.class

873

)

874

})

875

@NamedStoredProcedureQueries({

876

@NamedStoredProcedureQuery(

877

name = "User.calculateDiscount",

878

procedureName = "sp_calculate_user_discount",

879

parameters = {

880

@StoredProcedureParameter(name = "userId", type = Long.class, mode = ParameterMode.IN),

881

@StoredProcedureParameter(name = "discount", type = BigDecimal.class, mode = ParameterMode.OUT)

882

}

883

)

884

})

885

public class User {

886

@Id

887

private Long id;

888

private String name;

889

private String email;

890

private boolean active;

891

892

@OneToMany(mappedBy = "user")

893

private List<Order> orders;

894

}

895

896

// Using named queries

897

TypedQuery<User> query = em.createNamedQuery("User.findByEmail", User.class);

898

query.setParameter("email", "alice@example.com");

899

User user = query.getSingleResult();

900

901

Query nativeQuery = em.createNamedQuery("User.findByNativeSQL");

902

nativeQuery.setParameter(1, "A%");

903

List<User> users = nativeQuery.getResultList();

904

905

StoredProcedureQuery spQuery = em.createNamedStoredProcedureQuery("User.calculateDiscount");

906

spQuery.setParameter("userId", 1L);

907

spQuery.execute();

908

BigDecimal discount = (BigDecimal) spQuery.getOutputParameterValue("discount");

909

```

910

911

### SQL Result Set Mapping

912

913

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

914

915

```java { .api }

916

/**

917

* Specifies the mapping of the result of a native SQL query or stored procedure

918

* @since 1.0

919

*/

920

@Target({TYPE})

921

@Retention(RUNTIME)

922

@Repeatable(SqlResultSetMappings.class)

923

public @interface SqlResultSetMapping {

924

/** (Required) The name of the result set mapping */

925

String name();

926

927

/** (Optional) Entities to map to */

928

EntityResult[] entities() default {};

929

930

/** (Optional) Constructor results */

931

ConstructorResult[] classes() default {};

932

933

/** (Optional) Column results */

934

ColumnResult[] columns() default {};

935

}

936

937

/**

938

* Groups SqlResultSetMapping annotations

939

* @since 1.0

940

*/

941

@Target({TYPE})

942

@Retention(RUNTIME)

943

public @interface SqlResultSetMappings {

944

/** Array of result set mappings */

945

SqlResultSetMapping[] value();

946

}

947

948

/**

949

* Used to map a SQL result to an entity

950

* @since 1.0

951

*/

952

@Target({})

953

@Retention(RUNTIME)

954

public @interface EntityResult {

955

/** (Required) The class of the entity */

956

Class entityClass();

957

958

/** (Optional) Field mappings */

959

FieldResult[] fields() default {};

960

961

/** (Optional) The name of the discriminator column */

962

String discriminatorColumn() default "";

963

}

964

965

/**

966

* Used to map columns to entity fields

967

* @since 1.0

968

*/

969

@Target({})

970

@Retention(RUNTIME)

971

public @interface FieldResult {

972

/** (Required) Name of the persistent field or property */

973

String name();

974

975

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

976

String column();

977

}

978

979

/**

980

* Used to map SQL query results to a constructor

981

* @since 2.1

982

*/

983

@Target({})

984

@Retention(RUNTIME)

985

public @interface ConstructorResult {

986

/** (Required) The class whose constructor is to be invoked */

987

Class targetClass();

988

989

/** (Required) The columns to be passed to the constructor */

990

ColumnResult[] columns();

991

}

992

993

/**

994

* Used to map a column in the SELECT list to a constructor parameter or scalar result

995

* @since 1.0

996

*/

997

@Target({})

998

@Retention(RUNTIME)

999

public @interface ColumnResult {

1000

/** (Required) The name of the column in the SELECT list */

1001

String name();

1002

1003

/** (Optional) The Java type of the column */

1004

Class type() default void.class;

1005

}

1006

```

1007

1008

**Usage Example:**

1009

1010

```java

1011

@Entity

1012

@SqlResultSetMappings({

1013

@SqlResultSetMapping(

1014

name = "UserOrderMapping",

1015

entities = {

1016

@EntityResult(

1017

entityClass = User.class,

1018

fields = {

1019

@FieldResult(name = "id", column = "user_id"),

1020

@FieldResult(name = "name", column = "user_name")

1021

}

1022

),

1023

@EntityResult(

1024

entityClass = Order.class,

1025

fields = {

1026

@FieldResult(name = "id", column = "order_id"),

1027

@FieldResult(name = "orderDate", column = "order_date")

1028

}

1029

)

1030

}

1031

),

1032

@SqlResultSetMapping(

1033

name = "UserSummaryMapping",

1034

classes = {

1035

@ConstructorResult(

1036

targetClass = UserSummary.class,

1037

columns = {

1038

@ColumnResult(name = "user_id", type = Long.class),

1039

@ColumnResult(name = "user_name", type = String.class),

1040

@ColumnResult(name = "order_count", type = Long.class)

1041

}

1042

)

1043

}

1044

),

1045

@SqlResultSetMapping(

1046

name = "ScalarMapping",

1047

columns = {

1048

@ColumnResult(name = "total", type = BigDecimal.class),

1049

@ColumnResult(name = "count", type = Long.class)

1050

}

1051

)

1052

})

1053

public class User {

1054

@Id

1055

private Long id;

1056

private String name;

1057

}

1058

1059

// Using result set mapping

1060

Query query = em.createNativeQuery(

1061

"SELECT u.id as user_id, u.name as user_name, o.id as order_id, o.order_date " +

1062

"FROM users u JOIN orders o ON u.id = o.user_id",

1063

"UserOrderMapping"

1064

);

1065

List results = query.getResultList();

1066

1067

// Constructor result mapping

1068

Query summaryQuery = em.createNativeQuery(

1069

"SELECT u.id as user_id, u.name as user_name, COUNT(o.id) as order_count " +

1070

"FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name",

1071

"UserSummaryMapping"

1072

);

1073

List<UserSummary> summaries = summaryQuery.getResultList();

1074

1075

// Scalar result mapping

1076

Query scalarQuery = em.createNativeQuery(

1077

"SELECT SUM(amount) as total, COUNT(*) as count FROM orders",

1078

"ScalarMapping"

1079

);

1080

Object[] result = (Object[]) scalarQuery.getSingleResult();

1081

BigDecimal total = (BigDecimal) result[0];

1082

Long count = (Long) result[1];

1083

```

1084

1085

### Tuple Results

1086

1087

Work with multi-column query results.

1088

1089

```java { .api }

1090

/**

1091

* Interface for extracting values from Tuple results

1092

* @since 2.0

1093

*/

1094

public interface Tuple {

1095

/**

1096

* Get the value of the specified element

1097

* @param tupleElement tuple element

1098

* @return value

1099

*/

1100

<X> X get(TupleElement<X> tupleElement);

1101

1102

/**

1103

* Get the value at the specified position

1104

* @param i position (numbered from 0)

1105

* @param type the type of the result

1106

* @return value

1107

*/

1108

<X> X get(int i, Class<X> type);

1109

1110

/**

1111

* Get the value at the specified position

1112

* @param i position (numbered from 0)

1113

* @return value

1114

*/

1115

Object get(int i);

1116

1117

/**

1118

* Get the value by alias

1119

* @param alias alias name

1120

* @param type the type of the result

1121

* @return value

1122

*/

1123

<X> X get(String alias, Class<X> type);

1124

1125

/**

1126

* Get the value by alias

1127

* @param alias alias name

1128

* @return value

1129

*/

1130

Object get(String alias);

1131

1132

/**

1133

* Return the values of the tuple as an array

1134

* @return array of values

1135

*/

1136

Object[] toArray();

1137

1138

/**

1139

* Return the tuple elements

1140

* @return tuple elements

1141

*/

1142

List<TupleElement<?>> getElements();

1143

}

1144

1145

/**

1146

* Represents a tuple element

1147

* @since 2.0

1148

*/

1149

public interface TupleElement<X> {

1150

/**

1151

* Return the Java type of the element

1152

* @return Java type

1153

*/

1154

Class<? extends X> getJavaType();

1155

1156

/**

1157

* Return the alias of the element

1158

* @return alias

1159

*/

1160

String getAlias();

1161

}

1162

```

1163

1164

**Usage Example:**

1165

1166

```java

1167

EntityManager em = emf.createEntityManager();

1168

1169

// Tuple query

1170

CriteriaBuilder cb = em.getCriteriaBuilder();

1171

CriteriaQuery<Tuple> cq = cb.createTupleQuery();

1172

Root<User> user = cq.from(User.class);

1173

cq.multiselect(

1174

user.get("id").alias("userId"),

1175

user.get("name").alias("userName"),

1176

cb.count(user.get("orders")).alias("orderCount")

1177

);

1178

cq.groupBy(user.get("id"), user.get("name"));

1179

1180

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

1181

List<Tuple> results = query.getResultList();

1182

1183

for (Tuple tuple : results) {

1184

Long id = tuple.get("userId", Long.class);

1185

String name = tuple.get("userName", String.class);

1186

Long count = tuple.get("orderCount", Long.class);

1187

System.out.println(name + " has " + count + " orders");

1188

}

1189

```

1190