You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The only difference between `createSelectionQuery()` and `createQuery()` is that `createSelectionQuery()` throws an exception if passed an `insert`, `delete`, or `update`.
61
+
The main difference between `createSelectionQuery()` and `createQuery()` is that `createSelectionQuery()` throws an exception if passed a query string that begins with `insert`, `delete`, or `update`.
62
62
63
-
In the query above, `:titleSearchPattern` is called a _named parameter_.
64
-
We may also identify parameters by a number.
65
-
These are called _ordinal parameters_.
63
+
We've been using link:{doc-javadoc-url}org/hibernate/query/SelectionQuery.html#getResultList()[`getResultList()`] because we've been expecting our queries to return multiple results.
64
+
If we're expecting a query to return a single result, we can use link:{doc-javadoc-url}org/hibernate/query/SelectionQuery.html#getSingleResult()[`getSingleResult()`].
65
+
66
+
[source,java]
67
+
----
68
+
Book book =
69
+
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
70
+
.setParameter(1, isbn)
71
+
.getSingleResult();
72
+
----
73
+
74
+
Or, if we're expecting it to return at most one result, we can use link:{doc-javadoc-url}org/hibernate/query/SelectionQuery.html#getSingleResultOrNull()[`getSingleResultOrNull()`].
75
+
76
+
[source,java]
77
+
----
78
+
Book bookOrNull =
79
+
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
80
+
.setParameter(1, isbn)
81
+
.getSingleResultOrNull();
82
+
----
83
+
84
+
The difference, of course, is that `getSingleResult()` throws an exception if there's no matching row in the database, whereas `getSingleResultOrNull()` just returns `null`.
85
+
86
+
To execute a `MutationQuery`, we use link:{doc-javadoc-url}org/hibernate/query/MutationQuery.html#executeUpdate()[`executeUpdate()`], which returns the number of entities affected by the `insert`, `update`, or `delete`.
87
+
88
+
[[query-parameters]]
89
+
=== Query parameters
90
+
91
+
Queries are often parameterized.
92
+
93
+
- In the query above, `:titleSearchPattern` is called a _named parameter_.
94
+
- Alternatively, we may label a parameter by a number. Such a parameter is called an _ordinal parameter_.
95
+
96
+
We may easily rewrite our query to use an ordinal parameter:
66
97
67
98
[source,java]
68
99
----
@@ -81,45 +112,61 @@ _Never_ concatenate user input with HQL and pass the concatenated string to `cre
81
112
This would open up the possibility for an attacker to execute arbitrary code on your database server.
82
113
====
83
114
84
-
If we're expecting a query to return a single result, we can use `getSingleResult()`.
115
+
The link:{doc-javadoc-url}org/hibernate/query/CommonQueryContract.html#setParameter(java.lang.String,java.lang.Object)[`setParameter()`] methods specify arguments to query parameters.
116
+
117
+
[TIP]
118
+
====
119
+
The two-argument forms of `setParameter()` are perfect for most purposes, but _very occasionally_ it's necessary to resolve an ambiguity in the interpretation of the argument value by explicitly specifying the <<compositional-basic-types,type>> of the argument.
120
+
The best way to identify the type is via a reference to a JPA metamodel `Type`.
121
+
There are two ways to do this:
122
+
123
+
// - by passing a Java `Class` as a third argument to link:{doc-javadoc-url}org/hibernate/query/CommonQueryContract.html#setParameter(java.lang.String,java.lang.Object,java.lang.Class)[`setParameter()`] (this doesn't usually help very much),
124
+
- by passing the `Type` as a third argument to link:{doc-javadoc-url}org/hibernate/query/CommonQueryContract.html#setParameter(java.lang.String,java.lang.Object,jakarta.persistence.metamodel.Type)[`setParameter()`], or
125
+
- by packaging the argument and its `Type` in a link:{doc-javadoc-url}org/hibernate/query/TypedParameterValue.html[`TypedParameterValue`].
126
+
127
+
For example, we may pass a <<static-metamodel,static metamodel>> reference to `setParameter()`.
85
128
86
129
[source,java]
87
130
----
88
-
Book book =
89
-
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
90
-
.setParameter(1, isbn)
91
-
.getSingleResult();
131
+
session.createSelectionQuery("from Person where address = :address")
By default, Hibernate dirty checks entities in the persistence context before executing a query, in order to determine if there are changes which have not yet been flushed to the database, but which might affect the results of the query.
141
+
If there are unflushed changes, then Hibernate goes ahead and executes an automatic <<flush,flush>> before executing the query.
142
+
That way, the query won't return stale results which fail to reflect changes made to data within the current unit of work.
143
+
But if there are many entities association with the persistence context, then this can be an expensive operation.
93
144
94
-
Or, if we're expecting it to return at most one result, we can use `getSingleResultOrNull()`.
145
+
To disable this behavior, set the link:{doc-javadoc-url}org/hibernate/query/QueryFlushMode.html[query flush mode] to `NO_FLUSH`:
95
146
96
147
[source,java]
97
148
----
98
149
Book bookOrNull =
99
150
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
100
151
.setParameter(1, isbn)
101
-
.getSingleResultOrNull();
152
+
.setQueryFlushMode(QueryFlushMode.NO_FLUSH)
153
+
.getSingleResult();
102
154
----
103
155
104
-
The difference, of course, is that `getSingleResult()` throws an exception if there's no matching row in the database, whereas `getSingleResultOrNull()` just returns `null`.
105
-
106
-
By default, Hibernate dirty checks entities in the persistence context before executing a query, in order to determine if the session should be flushed.
107
-
If there are many entities association with the persistence context, then this can be an expensive operation.
108
-
109
-
To disable this behavior, set the flush mode to `COMMIT` or `MANUAL`:
156
+
Or, especially if you're using JPA-standard APIs, use `FlushModeType.COMMIT`:
110
157
111
158
[source,java]
112
159
----
113
160
Book bookOrNull =
114
161
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
115
162
.setParameter(1, isbn)
116
-
.setHibernateFlushMode(MANUAL)
163
+
.setFlushMode(FlushModeType.COMMIT)
117
164
.getSingleResult();
118
165
----
119
166
120
167
[CAUTION]
121
168
====
122
-
Setting the flush mode to `COMMIT` or `MANUAL` might cause the query to return stale results.
169
+
Setting the flush mode to `NO_FLUSH`, `COMMIT`, or `MANUAL` might cause the query to return stale results.
123
170
====
124
171
125
172
Occasionally we need to build a query at runtime, from a set of optional conditions.
| Mutation | link:{doc-javadoc-url}org/hibernate/query/QueryProducer.html#createMutationQuery(jakarta.persistence.criteria.CriteriaUpdate)[`createMutationQuery(CriteriaUpdate)`] or link:{doc-javadoc-url}org/hibernate/query/QueryProducer.html#createMutationQuery(jakarta.persistence.criteria.CriteriaDelete)[`createMutationQuery(CriteriaDelete)`] |`createQuery(CriteriaUpdate)` or `createQuery(CriteriaDelete)` | `executeUpdate()`
215
263
|===
216
264
217
265
For example:
@@ -261,8 +309,8 @@ The reason it works this way is that each JPA provider has its own implementatio
261
309
// [%unbreakable]
262
310
// [TIP]
263
311
// ====
264
-
Hibernate 6.3 introduces the helper class link:{doc-javadoc-url}org/hibernate/query/criteria/CriteriaDefinition.html[`CriteriaDefinition`] to reduce the verbosity of criteria queries.
265
-
Our example looks like this:
312
+
The helper class link:{doc-javadoc-url}org/hibernate/query/criteria/CriteriaDefinition.html[`CriteriaDefinition`] can reduce the verbosity of criteria queries by eliminating the need to explicitly qualify calls to the methods of `CriteriaBuilder`.
313
+
Our <<criteria-query-example,previous example>> would look like this:
266
314
267
315
[source,java]
268
316
----
@@ -295,9 +343,9 @@ As we said <<introduction,right up front>>, Hibernate's generated SQL is meant t
0 commit comments