HHH-15055 - Document SelectionQuery and MutationQuery
This commit is contained in:
parent
a7da40709c
commit
86cdf67016
|
@ -28,6 +28,8 @@ Each serves a different purpose depending on the expected type of the query resu
|
|||
====
|
||||
The chapter 6 (i.e., Criteria API) of the Jakarta Persistence Specification already contains a decent amount of reference material pertaining to the various parts of a criteria query.
|
||||
So rather than duplicate all that content here, let's instead look at some of the more widely anticipated usages of the API.
|
||||
|
||||
|
||||
====
|
||||
|
||||
[[criteria-typedquery]]
|
||||
|
|
|
@ -21,6 +21,12 @@ However, HQL is the most convenient option for most people most of the time.
|
|||
The actual query language itself is discussed the <<chapters/query/criteria/QueryLanguage.adoc#query-language,next chapter>>.
|
||||
This chapter describes the Java APIs for executing HQL and JPQL queries.
|
||||
|
||||
Most of this chapter is dedicated to discussing `org.hibernate.query.Query`, `jakarta.persistence.Query` and
|
||||
`jakarta.persistence.TypedQuery`. These `Query` contracts mix the ability to perform selections as well mutations.
|
||||
Hibernate additionally offers the more targeted `SelectionQuery` and `MutationQuery` contracts. See
|
||||
<<hql-SelectionQuery>> and <<hql-MutationQuery>> for additional details.
|
||||
|
||||
|
||||
[[hql-examples-domain-model]]
|
||||
=== Example domain model
|
||||
|
||||
|
@ -573,3 +579,71 @@ The setting gives the maximum number of `ParameterMetadataImpl` instances mainta
|
|||
Now, if you have many JPQL or Criteria API queries, it's a good idea to increase the query plan cache size so that the vast majority of executing entity queries can skip the compilation phase, therefore reducing execution time.
|
||||
|
||||
To get a better understanding of the query plan cache effectiveness, Hibernate offers several statistics you can use. For more details, check out the <<chapters/statistics/Statistics.adoc#statistics-query-plan-cache,Query plan cache statistics>> section.
|
||||
|
||||
|
||||
[[hql-SelectionQuery]]
|
||||
=== SelectionQuery
|
||||
|
||||
Hibernate's `SelectionQuery` contract is similar to `Query` but only exposes methods which are relevant to selection queries. For example,
|
||||
it does not expose a `#executeUpdate` method. This allows for earlier validation of the query as a selection.
|
||||
|
||||
|
||||
[[hql-examples-selection-query]]
|
||||
.Selection query validation
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/SelectionQueryExampleTests.java[tags=example-hql-selection-query]
|
||||
|
||||
include::{sourcedir}/SelectionQueryExampleTests.java[tags=example-hql-selection-query-query]
|
||||
----
|
||||
====
|
||||
|
||||
`SelectionQuery` may also be used with named-queries
|
||||
|
||||
[[hql-examples-named-selection-query]]
|
||||
.NamedQuery selection validation
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/SelectionQueryExampleTests.java[tags=example-hql-named-selection-query]
|
||||
|
||||
include::{sourcedir}/SelectionQueryExampleTests.java[tags=example-hql-named-selection-query-query]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[hql-MutationQuery]]
|
||||
=== MutationQuery
|
||||
|
||||
Along the same lines as `SelectionQuery`, `MutationQuery` is similar to `Query` but only exposes methods which are relevant to mutation queries.
|
||||
For example, in terms of execution, it only exposes `#executeUpdate` method. This allows for earlier validation of the query as a mutation.
|
||||
|
||||
[[hql-examples-mutation-query]]
|
||||
.Mutation query validation
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/MutationQueryExampleTests.java[tags=example-hql-mutation-query]
|
||||
|
||||
include::{sourcedir}/MutationQueryExampleTests.java[tags=example-hql-mutation-query-query]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
`MutationQuery` may also be used with named-queries
|
||||
|
||||
[[hql-examples-named-mutation-query]]
|
||||
.NamedQuery mutation validation
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{sourcedir}/MutationQueryExampleTests.java[tags=example-hql-named-mutation-query]
|
||||
|
||||
include::{sourcedir}/MutationQueryExampleTests.java[tags=example-hql-named-mutation-query-query]
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
|
|
|
@ -160,6 +160,10 @@ import jakarta.persistence.Version;
|
|||
}
|
||||
)
|
||||
//end::jpa-read-only-entities-native-example[]
|
||||
@NamedQuery(
|
||||
name = "delete_person",
|
||||
query = "delete Person"
|
||||
)
|
||||
//tag::sql-sp-ref-cursor-oracle-named-query-example[]
|
||||
@NamedStoredProcedureQuery(
|
||||
name = "sp_person_phones",
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.userguide.hql;
|
||||
|
||||
import org.hibernate.query.MutationQuery;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.hibernate.userguide.model.Account;
|
||||
import org.hibernate.userguide.model.Call;
|
||||
import org.hibernate.userguide.model.CreditCardPayment;
|
||||
import org.hibernate.userguide.model.Person;
|
||||
import org.hibernate.userguide.model.Phone;
|
||||
import org.hibernate.userguide.model.WireTransferPayment;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
Person.class,
|
||||
Phone.class,
|
||||
Call.class,
|
||||
Account.class,
|
||||
CreditCardPayment.class,
|
||||
WireTransferPayment.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class MutationQueryExampleTests {
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal mutation query" )
|
||||
public void queryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-mutation-query-query[]
|
||||
// cannot be validated until execution
|
||||
Query<Person> query = session.createQuery( "select p from Person p", Person.class );
|
||||
query.executeUpdate();
|
||||
//end::example-hql-mutation-query-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal mutation query" )
|
||||
public void selectionQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-mutation-query[]
|
||||
// can be validated while creating the MutationQuery
|
||||
MutationQuery badQuery = session.createMutationQuery( "select p from Person p" );
|
||||
//end::example-hql-mutation-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal mutation query" )
|
||||
public void namedSelectionQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-named-mutation-query[]
|
||||
// can be validated while creating the MutationQuery
|
||||
MutationQuery badQuery = session.createNamedMutationQuery( "get_person_by_name" );
|
||||
//end::example-hql-named-mutation-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal mutation query" )
|
||||
public void namedQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-named-mutation-query-query[]
|
||||
// cannot be validated until execution
|
||||
Query query = session.createNamedQuery( "get_person_by_name" );
|
||||
query.getResultList();
|
||||
//end::example-hql-named-mutation-query-query[]
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.userguide.hql;
|
||||
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.userguide.model.Account;
|
||||
import org.hibernate.userguide.model.Call;
|
||||
import org.hibernate.userguide.model.CreditCardPayment;
|
||||
import org.hibernate.userguide.model.Person;
|
||||
import org.hibernate.userguide.model.Phone;
|
||||
import org.hibernate.userguide.model.WireTransferPayment;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
Person.class,
|
||||
Phone.class,
|
||||
Call.class,
|
||||
Account.class,
|
||||
CreditCardPayment.class,
|
||||
WireTransferPayment.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class SelectionQueryExampleTests {
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal selection query" )
|
||||
public void selectionQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-selection-query[]
|
||||
// can be validated while creating the SelectionQuery
|
||||
SelectionQuery<?> badQuery = session.createSelectionQuery( "delete Person" );
|
||||
//end::example-hql-selection-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal selection query" )
|
||||
public void queryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-selection-query-query[]
|
||||
// cannot be validated until execution
|
||||
Query query = session.createQuery( "delete Person" );
|
||||
query.getResultList();
|
||||
//end::example-hql-selection-query-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal selection query" )
|
||||
public void namedSelectionQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-named-selection-query[]
|
||||
// can be validated while creating the SelectionQuery
|
||||
SelectionQuery<?> badQuery = session.getNamedQuery( "delete_Person" );
|
||||
//end::example-hql-named-selection-query[]
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( reason = "Illegal selection query" )
|
||||
public void namedQueryTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
//tag::example-hql-named-selection-query-query[]
|
||||
// cannot be validated until execution
|
||||
Query query = session.getNamedQuery( "delete_Person" );
|
||||
query.getResultList();
|
||||
//end::example-hql-named-selection-query-query[]
|
||||
} );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue