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
+
90
+
Queries are often parameterized.
91
+
92
+
- In the query above, `:titleSearchPattern` is called a _named parameter_.
93
+
- Alternatively, we may label a parameter by a number. Such a parameter is called an _ordinal parameter_.
94
+
95
+
We may easily rewrite our query to use an ordinal parameter:
66
96
67
97
[source,java]
68
98
----
@@ -81,45 +111,60 @@ _Never_ concatenate user input with HQL and pass the concatenated string to `cre
81
111
This would open up the possibility for an attacker to execute arbitrary code on your database server.
82
112
====
83
113
84
-
If we're expecting a query to return a single result, we can use `getSingleResult()`.
114
+
The link:{doc-javadoc-url}org/hibernate/query/CommonQueryContract.html#setParameter(java.lang.String,java.lang.Object)[`setParameter()`] methods specify arguments to query parameters.
115
+
116
+
[TIP]
117
+
====
118
+
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.
119
+
The best way to identify the type is via a reference to a JPA metamodel `Type`.
120
+
There are two ways to do this:
121
+
122
+
// - 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),
123
+
- 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
124
+
- by packaging the argument and its `Type` in a link:{doc-javadoc-url}org/hibernate/query/TypedParameterValue.html[`TypedParameterValue`].
125
+
126
+
For example, we may pass a <<static-metamodel,static metamodel>> reference to `setParameter()`.
85
127
86
128
[source,java]
87
129
----
88
-
Book book =
89
-
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
90
-
.setParameter(1, isbn)
91
-
.getSingleResult();
130
+
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.
139
+
If there are unflushed changes, then Hibernate goes ahead and executes an automatic <<flush,flush>> before executing the query.
140
+
That way, the query won't return stale results which fail to reflect changes made to data within the current unit of work.
141
+
But if there are many entities association with the persistence context, then this can be an expensive operation.
93
142
94
-
Or, if we're expecting it to return at most one result, we can use `getSingleResultOrNull()`.
143
+
To disable this behavior, set the link:{doc-javadoc-url}org/hibernate/query/QueryFlushMode.html[query flush mode] to `NO_FLUSH`:
95
144
96
145
[source,java]
97
146
----
98
147
Book bookOrNull =
99
148
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
100
149
.setParameter(1, isbn)
101
-
.getSingleResultOrNull();
150
+
.setQueryFlushMode(QueryFlushMode.NO_FLUSH)
151
+
.getSingleResult();
102
152
----
103
153
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`:
154
+
Or, especially if you're using JPA-standard APIs, use `FlushModeType.COMMIT`:
110
155
111
156
[source,java]
112
157
----
113
158
Book bookOrNull =
114
159
session.createSelectionQuery("from Book where isbn = ?1", Book.class)
115
160
.setParameter(1, isbn)
116
-
.setHibernateFlushMode(MANUAL)
161
+
.setFlushMode(FlushModeType.COMMIT)
117
162
.getSingleResult();
118
163
----
119
164
120
165
[CAUTION]
121
166
====
122
-
Setting the flush mode to `COMMIT` or `MANUAL` might cause the query to return stale results.
167
+
Setting the flush mode to `NO_FLUSH`, `COMMIT`, or `MANUAL` might cause the query to return stale results.
123
168
====
124
169
125
170
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
261
|===
216
262
217
263
For example:
@@ -261,8 +307,8 @@ The reason it works this way is that each JPA provider has its own implementatio
261
307
// [%unbreakable]
262
308
// [TIP]
263
309
// ====
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:
310
+
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`.
311
+
Our <<criteria-query-example,previous example>> would look like this:
266
312
267
313
[source,java]
268
314
----
@@ -295,9 +341,9 @@ As we said <<introduction,right up front>>, Hibernate's generated SQL is meant t
0 commit comments