0
# Query APIs
1
2
Hibernate Core provides comprehensive querying capabilities through multiple APIs including HQL (Hibernate Query Language), JPQL (Jakarta Persistence Query Language), Criteria API, and native SQL queries. All query types support parameter binding, pagination, and result mapping.
3
4
## Capabilities
5
6
### Query Interface
7
8
Base interface for all query types providing common query operations.
9
10
```java { .api }
11
/**
12
* Base interface for all query types
13
* @param <R> the result type
14
*/
15
public interface Query<R> extends CommonQueryContract {
16
// Result retrieval
17
18
/**
19
* Execute the query and return the result list
20
* @return list of query results
21
*/
22
List<R> getResultList();
23
24
/**
25
* Execute the query and return a single result
26
* @return single query result
27
* @throws NonUniqueResultException if more than one result
28
* @throws NoResultException if no result found
29
*/
30
R getSingleResult();
31
32
/**
33
* Execute the query and return a single result or null
34
* @return single query result or null if not found
35
* @throws NonUniqueResultException if more than one result
36
*/
37
R getSingleResultOrNull();
38
39
/**
40
* Execute the query and return the result list (Hibernate-specific)
41
* @return list of query results
42
*/
43
List<R> list();
44
45
/**
46
* Execute the query and return results as a Stream
47
* @return Stream of query results (must be closed after use)
48
*/
49
Stream<R> stream();
50
51
/**
52
* Execute the query and return results as a Stream (JPA standard method)
53
* @return Stream of query results (must be closed after use)
54
*/
55
Stream<R> getResultStream();
56
57
// Parameter binding
58
59
/**
60
* Bind a value to a named parameter
61
* @param name the parameter name
62
* @param value the parameter value
63
* @return this Query for chaining
64
*/
65
<P> Query<R> setParameter(String name, P value);
66
67
/**
68
* Bind a value to a positional parameter
69
* @param position the parameter position (1-based)
70
* @param value the parameter value
71
* @return this Query for chaining
72
*/
73
<P> Query<R> setParameter(int position, P value);
74
75
/**
76
* Bind a temporal value with specific temporal type
77
* @param name the parameter name
78
* @param value the temporal value
79
* @param temporalType the temporal type
80
* @return this Query for chaining
81
*/
82
Query<R> setParameter(String name, Object value, TemporalType temporalType);
83
84
/**
85
* Bind multiple parameters from a map
86
* @param parameters map of parameter names to values
87
* @return this Query for chaining
88
*/
89
Query<R> setParameters(Map<String, Object> parameters);
90
91
// Pagination
92
93
/**
94
* Set the position of the first result to retrieve
95
* @param startPosition position of the first result (0-based)
96
* @return this Query for chaining
97
*/
98
Query<R> setFirstResult(int startPosition);
99
100
/**
101
* Set the maximum number of results to retrieve
102
* @param maxResult maximum number of results
103
* @return this Query for chaining
104
*/
105
Query<R> setMaxResults(int maxResult);
106
107
// Query configuration
108
109
/**
110
* Set the query timeout in seconds
111
* @param timeout timeout in seconds
112
* @return this Query for chaining
113
*/
114
Query<R> setTimeout(int timeout);
115
116
/**
117
* Set the fetch size hint
118
* @param size the fetch size
119
* @return this Query for chaining
120
*/
121
Query<R> setFetchSize(int size);
122
123
/**
124
* Set the cache mode for this query
125
* @param cacheMode the cache mode
126
* @return this Query for chaining
127
*/
128
Query<R> setCacheMode(CacheMode cacheMode);
129
130
/**
131
* Enable or disable query result caching
132
* @param cacheable whether to cache results
133
* @return this Query for chaining
134
*/
135
Query<R> setCacheable(boolean cacheable);
136
137
/**
138
* Set the cache region for this query
139
* @param region the cache region name
140
* @return this Query for chaining
141
*/
142
Query<R> setCacheRegion(String region);
143
}
144
```
145
146
### SelectionQuery Interface
147
148
Specialized interface for selection queries with additional ordering capabilities.
149
150
```java { .api }
151
/**
152
* Interface for selection queries (SELECT statements)
153
* @param <R> the result type
154
*/
155
public interface SelectionQuery<R> extends Query<R> {
156
/**
157
* Set the order for the query results
158
* @param orderList list of Order instances
159
* @return this SelectionQuery for chaining
160
*/
161
SelectionQuery<R> setOrder(List<Order> orderList);
162
163
/**
164
* Set the order for the query results
165
* @param orders Order instances
166
* @return this SelectionQuery for chaining
167
*/
168
SelectionQuery<R> setOrder(Order... orders);
169
170
/**
171
* Apply pagination using Page object
172
* @param page the page specification
173
* @return this SelectionQuery for chaining
174
*/
175
SelectionQuery<R> setPage(Page page);
176
177
/**
178
* Get results as a KeyedResultList
179
* @param keyFunction function to extract keys from results
180
* @return KeyedResultList instance
181
*/
182
<K> KeyedResultList<K, R> getKeyedResultList(Function<R, K> keyFunction);
183
184
/**
185
* Execute query and return scrollable results
186
* @return ScrollableResults for the query
187
*/
188
ScrollableResults<R> scroll();
189
190
/**
191
* Execute query and return scrollable results with scroll mode
192
* @param scrollMode the scroll mode to use
193
* @return ScrollableResults for the query
194
*/
195
ScrollableResults<R> scroll(ScrollMode scrollMode);
196
}
197
```
198
199
### NativeQuery Interface
200
201
Interface for native SQL queries with additional SQL-specific features.
202
203
```java { .api }
204
/**
205
* Interface for native SQL queries
206
* @param <R> the result type
207
*/
208
public interface NativeQuery<R> extends Query<R> {
209
/**
210
* Add an entity to the result set
211
* @param alias the alias for the entity
212
* @param entityClass the entity class
213
* @return this NativeQuery for chaining
214
*/
215
NativeQuery<R> addEntity(String alias, Class<?> entityClass);
216
217
/**
218
* Add a join to an entity
219
* @param alias the alias for the join
220
* @param path the property path
221
* @return this NativeQuery for chaining
222
*/
223
NativeQuery<R> addJoin(String alias, String path);
224
225
/**
226
* Add a scalar column to the result set
227
* @param columnAlias the column alias
228
* @param type the Hibernate type
229
* @return this NativeQuery for chaining
230
*/
231
NativeQuery<R> addScalar(String columnAlias, BasicType<?> type);
232
233
/**
234
* Add a scalar column with automatic type detection
235
* @param columnAlias the column alias
236
* @return this NativeQuery for chaining
237
*/
238
NativeQuery<R> addScalar(String columnAlias);
239
240
/**
241
* Set the result set mapping name
242
* @param name the result set mapping name
243
* @return this NativeQuery for chaining
244
*/
245
NativeQuery<R> setResultSetMapping(String name);
246
247
/**
248
* Enable synchronization with named queries
249
* @param querySpace the query space
250
* @return this NativeQuery for chaining
251
*/
252
NativeQuery<R> addSynchronizedQuerySpace(String querySpace);
253
254
/**
255
* Enable synchronization with entity classes
256
* @param entityClass the entity class
257
* @return this NativeQuery for chaining
258
*/
259
NativeQuery<R> addSynchronizedEntityClass(Class<?> entityClass);
260
}
261
```
262
263
### MutationQuery Interface
264
265
Interface for update and delete queries.
266
267
```java { .api }
268
/**
269
* Interface for mutation queries (UPDATE, DELETE)
270
*/
271
public interface MutationQuery extends CommonQueryContract {
272
/**
273
* Execute the update or delete statement
274
* @return number of entities updated or deleted
275
*/
276
int executeUpdate();
277
278
/**
279
* Bind a value to a named parameter
280
* @param name the parameter name
281
* @param value the parameter value
282
* @return this MutationQuery for chaining
283
*/
284
<P> MutationQuery setParameter(String name, P value);
285
286
/**
287
* Bind a value to a positional parameter
288
* @param position the parameter position (1-based)
289
* @param value the parameter value
290
* @return this MutationQuery for chaining
291
*/
292
<P> MutationQuery setParameter(int position, P value);
293
294
/**
295
* Set the query timeout
296
* @param timeout timeout in seconds
297
* @return this MutationQuery for chaining
298
*/
299
MutationQuery setTimeout(int timeout);
300
}
301
```
302
303
### CriteriaQuery and CriteriaBuilder APIs
304
305
Type-safe programmatic query construction using the JPA Criteria API.
306
307
```java { .api }
308
/**
309
* Interface for building criteria queries
310
*/
311
public interface CriteriaBuilder {
312
/**
313
* Create a CriteriaQuery for the specified result type
314
* @param resultClass the result type
315
* @return CriteriaQuery instance
316
*/
317
<T> CriteriaQuery<T> createQuery(Class<T> resultClass);
318
319
/**
320
* Create a tuple CriteriaQuery
321
* @return CriteriaQuery for Tuple results
322
*/
323
CriteriaQuery<Tuple> createTupleQuery();
324
325
/**
326
* Create a criteria update query
327
* @param targetEntity the entity to update
328
* @return CriteriaUpdate instance
329
*/
330
<T> CriteriaUpdate<T> createCriteriaUpdate(Class<T> targetEntity);
331
332
/**
333
* Create a criteria delete query
334
* @param targetEntity the entity to delete
335
* @return CriteriaDelete instance
336
*/
337
<T> CriteriaDelete<T> createCriteriaDelete(Class<T> targetEntity);
338
339
// Predicate construction methods
340
Predicate and(Predicate... restrictions);
341
Predicate or(Predicate... restrictions);
342
Predicate not(Predicate restriction);
343
Predicate conjunction();
344
Predicate disjunction();
345
346
// Comparison predicates
347
Predicate equal(Expression<?> x, Object y);
348
Predicate notEqual(Expression<?> x, Object y);
349
<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y);
350
<Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Y y);
351
<Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> x, Y y);
352
<Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Y y);
353
354
// String predicates
355
Predicate like(Expression<String> x, String pattern);
356
Predicate notLike(Expression<String> x, String pattern);
357
358
// Collection predicates
359
Predicate isEmpty(Expression<? extends Collection<?>> collection);
360
Predicate isNotEmpty(Expression<? extends Collection<?>> collection);
361
Predicate isMember(Object elem, Expression<Collection<?>> collection);
362
363
// Null predicates
364
Predicate isNull(Expression<?> x);
365
Predicate isNotNull(Expression<?> x);
366
367
// Aggregate functions
368
<N extends Number> Expression<N> sum(Expression<N> x);
369
Expression<Long> count(Expression<?> x);
370
Expression<Long> countDistinct(Expression<?> x);
371
<N extends Number> Expression<N> avg(Expression<N> x);
372
<N extends Number> Expression<N> max(Expression<N> x);
373
<N extends Number> Expression<N> min(Expression<N> x);
374
375
// Ordering
376
Order asc(Expression<?> x);
377
Order desc(Expression<?> x);
378
}
379
380
/**
381
* Criteria query interface for type-safe querying
382
* @param <T> the result type
383
*/
384
public interface CriteriaQuery<T> extends AbstractQuery<T> {
385
/**
386
* Specify the selection
387
* @param selection the selection expression
388
* @return this CriteriaQuery
389
*/
390
CriteriaQuery<T> select(Selection<? extends T> selection);
391
392
/**
393
* Specify multiple selections for tuple results
394
* @param selections the selection expressions
395
* @return this CriteriaQuery
396
*/
397
CriteriaQuery<T> multiselect(Selection<?>... selections);
398
399
/**
400
* Create and add a root entity
401
* @param entityClass the entity class
402
* @return Root instance
403
*/
404
<X> Root<X> from(Class<X> entityClass);
405
406
/**
407
* Specify the where clause
408
* @param restriction the restriction predicate
409
* @return this CriteriaQuery
410
*/
411
CriteriaQuery<T> where(Predicate... restriction);
412
413
/**
414
* Specify group by expressions
415
* @param grouping the grouping expressions
416
* @return this CriteriaQuery
417
*/
418
CriteriaQuery<T> groupBy(Expression<?>... grouping);
419
420
/**
421
* Specify having clause
422
* @param restriction the having restriction
423
* @return this CriteriaQuery
424
*/
425
CriteriaQuery<T> having(Predicate... restriction);
426
427
/**
428
* Specify ordering
429
* @param orders the order expressions
430
* @return this CriteriaQuery
431
*/
432
CriteriaQuery<T> orderBy(Order... orders);
433
434
/**
435
* Specify distinct results
436
* @param distinct whether to return distinct results
437
* @return this CriteriaQuery
438
*/
439
CriteriaQuery<T> distinct(boolean distinct);
440
441
/**
442
* Get the query roots
443
* @return set of Root instances
444
*/
445
Set<Root<?>> getRoots();
446
}
447
448
/**
449
* Root entity in a criteria query
450
* @param <X> the entity type
451
*/
452
public interface Root<X> extends From<X, X> {
453
/**
454
* Create a join to a collection-valued association
455
* @param attributeName the attribute name
456
* @return Join instance
457
*/
458
<Y> Join<X, Y> join(String attributeName);
459
460
/**
461
* Create a join with specified join type
462
* @param attributeName the attribute name
463
* @param jt the join type
464
* @return Join instance
465
*/
466
<Y> Join<X, Y> join(String attributeName, JoinType jt);
467
468
/**
469
* Create a fetch join
470
* @param attributeName the attribute name
471
* @return Fetch instance
472
*/
473
<Y> Fetch<X, Y> fetch(String attributeName);
474
475
/**
476
* Create a fetch join with specified join type
477
* @param attributeName the attribute name
478
* @param jt the join type
479
* @return Fetch instance
480
*/
481
<Y> Fetch<X, Y> fetch(String attributeName, JoinType jt);
482
483
/**
484
* Get an attribute path
485
* @param attributeName the attribute name
486
* @return Path to the attribute
487
*/
488
<Y> Path<Y> get(String attributeName);
489
}
490
```
491
492
### Order and Pagination Support
493
494
Classes for specifying query ordering and pagination.
495
496
```java { .api }
497
/**
498
* Represents an order-by fragment
499
*/
500
public class Order {
501
/**
502
* Create an ascending order
503
* @param attribute the attribute name
504
* @return Order instance for ascending sort
505
*/
506
public static Order asc(String attribute);
507
508
/**
509
* Create a descending order
510
* @param attribute the attribute name
511
* @return Order instance for descending sort
512
*/
513
public static Order desc(String attribute);
514
515
/**
516
* Create an order with explicit direction
517
* @param attribute the attribute name
518
* @param ascending true for ascending, false for descending
519
* @return Order instance
520
*/
521
public static Order by(String attribute, boolean ascending);
522
523
/**
524
* Get the attribute name
525
* @return the attribute name
526
*/
527
public String getAttributeName();
528
529
/**
530
* Check if this is ascending order
531
* @return true if ascending
532
*/
533
public boolean isAscending();
534
}
535
536
/**
537
* Pagination specification
538
*/
539
public class Page {
540
/**
541
* Create a page specification
542
* @param size the page size
543
* @param number the page number (0-based)
544
* @return Page instance
545
*/
546
public static Page page(int size, int number);
547
548
/**
549
* Create first page with given size
550
* @param size the page size
551
* @return Page instance for first page
552
*/
553
public static Page first(int size);
554
555
/**
556
* Get the page size
557
* @return the page size
558
*/
559
public int getSize();
560
561
/**
562
* Get the page number
563
* @return the page number (0-based)
564
*/
565
public int getNumber();
566
567
/**
568
* Get the offset for this page
569
* @return the offset (0-based)
570
*/
571
public int getOffset();
572
}
573
```
574
575
### ScrollableResults Interface
576
577
Interface for scrollable query results providing cursor-like navigation.
578
579
```java { .api }
580
/**
581
* Interface for scrollable query results
582
* @param <R> the result type
583
*/
584
public interface ScrollableResults<R> extends AutoCloseable {
585
/**
586
* Move to the next result
587
* @return true if there is a next result
588
*/
589
boolean next();
590
591
/**
592
* Move to the previous result
593
* @return true if there is a previous result
594
*/
595
boolean previous();
596
597
/**
598
* Move to the first result
599
* @return true if there is a first result
600
*/
601
boolean first();
602
603
/**
604
* Move to the last result
605
* @return true if there is a last result
606
*/
607
boolean last();
608
609
/**
610
* Move to a specific position
611
* @param position the position to move to
612
* @return true if successful
613
*/
614
boolean setRowNumber(int position);
615
616
/**
617
* Get the current result
618
* @return the current result
619
*/
620
R get();
621
622
/**
623
* Get a specific column value
624
* @param column the column index
625
* @return the column value
626
*/
627
Object get(int column);
628
629
/**
630
* Get the current row number
631
* @return the current row number
632
*/
633
int getRowNumber();
634
635
/**
636
* Close the scrollable results
637
*/
638
void close();
639
}
640
```
641
642
## Usage Examples
643
644
### Basic HQL/JPQL Queries
645
646
```java
647
import org.hibernate.query.Query;
648
649
// Simple selection query
650
List<User> users = session.createQuery("FROM User u WHERE u.active = :active", User.class)
651
.setParameter("active", true)
652
.getResultList();
653
654
// Query with joins
655
List<Order> orders = session.createQuery(
656
"SELECT o FROM Order o JOIN FETCH o.items WHERE o.customer.name = :customerName",
657
Order.class)
658
.setParameter("customerName", "John Doe")
659
.getResultList();
660
661
// Projection query
662
List<Object[]> results = session.createQuery(
663
"SELECT u.name, COUNT(o) FROM User u LEFT JOIN u.orders o GROUP BY u.name")
664
.getResultList();
665
```
666
667
### Pagination and Ordering
668
669
```java
670
// Paginated query with ordering
671
List<User> users = session.createQuery("FROM User u", User.class)
672
.setOrder(Order.asc("name"), Order.desc("createdDate"))
673
.setFirstResult(0)
674
.setMaxResults(20)
675
.getResultList();
676
677
// Using Page object
678
Page page = Page.page(20, 0); // 20 items per page, first page
679
List<User> pagedUsers = session.createQuery("FROM User", User.class)
680
.setPage(page)
681
.getResultList();
682
```
683
684
### Native SQL Queries
685
686
```java
687
// Simple native query
688
List<User> users = session.createNativeQuery(
689
"SELECT * FROM users WHERE created_date > ?1", User.class)
690
.setParameter(1, LocalDate.now().minusDays(30))
691
.getResultList();
692
693
// Complex native query with result mapping
694
List<Object[]> results = session.createNativeQuery(
695
"SELECT u.name, COUNT(o.id) as order_count " +
696
"FROM users u LEFT JOIN orders o ON u.id = o.customer_id " +
697
"GROUP BY u.id, u.name")
698
.addScalar("name", StandardBasicTypes.STRING)
699
.addScalar("order_count", StandardBasicTypes.LONG)
700
.getResultList();
701
702
// Native query with entity result
703
List<User> users = session.createNativeQuery(
704
"SELECT {u.*} FROM users u WHERE u.status = :status", User.class)
705
.addEntity("u", User.class)
706
.setParameter("status", "ACTIVE")
707
.getResultList();
708
```
709
710
### Update and Delete Queries
711
712
```java
713
// Update query
714
int updatedCount = session.createMutationQuery(
715
"UPDATE User u SET u.lastLogin = :loginTime WHERE u.id = :userId")
716
.setParameter("loginTime", LocalDateTime.now())
717
.setParameter("userId", 123L)
718
.executeUpdate();
719
720
// Bulk delete query
721
int deletedCount = session.createMutationQuery(
722
"DELETE FROM Order o WHERE o.status = :status AND o.createdDate < :cutoffDate")
723
.setParameter("status", OrderStatus.CANCELLED)
724
.setParameter("cutoffDate", LocalDate.now().minusYears(1))
725
.executeUpdate();
726
```
727
728
### Named Queries
729
730
```java
731
// Using named query defined on entity
732
@Entity
733
@NamedQuery(name = "User.findByStatus",
734
query = "FROM User u WHERE u.status = :status")
735
public class User {
736
// entity definition
737
}
738
739
// Execute named query
740
List<User> activeUsers = session.createNamedQuery("User.findByStatus", User.class)
741
.setParameter("status", UserStatus.ACTIVE)
742
.getResultList();
743
```
744
745
### Scrollable Results for Large Datasets
746
747
```java
748
// Process large result set with scrollable results
749
try (ScrollableResults<User> results = session.createQuery("FROM User", User.class)
750
.scroll(ScrollMode.FORWARD_ONLY)) {
751
752
int count = 0;
753
while (results.next()) {
754
User user = results.get();
755
// Process user
756
processUser(user);
757
758
// Periodically flush and clear for memory management
759
if (++count % 100 == 0) {
760
session.flush();
761
session.clear();
762
}
763
}
764
}
765
```
766
767
### Query Optimization and Caching
768
769
```java
770
// Enable query result caching
771
List<User> users = session.createQuery("FROM User u WHERE u.department = :dept", User.class)
772
.setParameter("dept", "Engineering")
773
.setCacheable(true)
774
.setCacheRegion("user-queries")
775
.getResultList();
776
777
// Set fetch size for better performance
778
List<Order> orders = session.createQuery("FROM Order o JOIN FETCH o.items", Order.class)
779
.setFetchSize(100)
780
.getResultList();
781
782
// Query timeout
783
List<User> users = session.createQuery("FROM User", User.class)
784
.setTimeout(30) // 30 seconds
785
.getResultList();
786
```
787
788
## Query Performance Best Practices
789
790
### Efficient Querying Patterns
791
792
- Use `JOIN FETCH` to avoid N+1 select problems
793
- Leverage pagination for large result sets
794
- Use projections when you don't need full entity graphs
795
- Cache frequently used query results
796
- Set appropriate fetch sizes for large result sets
797
798
### Parameter Binding
799
800
Always use parameter binding to prevent SQL injection and improve performance:
801
802
```java
803
// Good: Uses parameter binding
804
Query<User> query = session.createQuery("FROM User u WHERE u.name = :name", User.class)
805
.setParameter("name", userName);
806
807
// Bad: String concatenation (SQL injection risk)
808
Query<User> query = session.createQuery("FROM User u WHERE u.name = '" + userName + "'", User.class);
809
```
810
811
### Criteria API Queries
812
813
```java
814
// Type-safe criteria query construction
815
CriteriaBuilder cb = session.getCriteriaBuilder();
816
CriteriaQuery<User> cq = cb.createQuery(User.class);
817
Root<User> user = cq.from(User.class);
818
819
// Simple criteria query
820
cq.select(user)
821
.where(cb.and(
822
cb.equal(user.get("active"), true),
823
cb.like(user.get("name"), "John%")
824
));
825
826
List<User> users = session.createQuery(cq).getResultList();
827
828
// Complex criteria query with joins
829
CriteriaQuery<Order> orderQuery = cb.createQuery(Order.class);
830
Root<Order> order = orderQuery.from(Order.class);
831
Join<Order, Customer> customer = order.join("customer");
832
833
orderQuery.select(order)
834
.where(cb.and(
835
cb.equal(customer.get("status"), CustomerStatus.ACTIVE),
836
cb.greaterThan(order.get("total"), new BigDecimal("100.00"))
837
))
838
.orderBy(cb.desc(order.get("createdDate")));
839
840
List<Order> orders = session.createQuery(orderQuery).getResultList();
841
842
// Criteria update query
843
CriteriaUpdate<User> updateQuery = cb.createCriteriaUpdate(User.class);
844
Root<User> userRoot = updateQuery.from(User.class);
845
846
updateQuery.set(userRoot.get("lastLogin"), LocalDateTime.now())
847
.where(cb.equal(userRoot.get("id"), userId));
848
849
int updatedCount = session.createMutationQuery(updateQuery).executeUpdate();
850
```