HHH-10808 - Update documentation according to 5.2 changes

This commit is contained in:
Vlad Mihalcea 2016-06-07 13:40:04 +03:00
parent 78de650efe
commit 5963183c4a
8 changed files with 107 additions and 47 deletions

View File

@ -67,7 +67,6 @@ dependencies {
testCompile( project(path: ':hibernate-core', configuration: 'tests') ) testCompile( project(path: ':hibernate-core', configuration: 'tests') )
testCompile( project(':hibernate-testing') ) testCompile( project(':hibernate-testing') )
// testCompile( project(path: ':hibernate-entitymanager', configuration: 'tests') )
testRuntime( libraries.h2 ) testRuntime( libraries.h2 )
testRuntime( libraries.hsqldb ) testRuntime( libraries.hsqldb )

View File

@ -28,7 +28,7 @@ In this case, you do _not_ need to call `addEntity()` anymore.
---- ----
List people = session List people = session
.getNamedQuery( "persons" ) .getNamedQuery( "persons" )
.setString( "namePattern", namePattern ) .setParameter( "namePattern", namePattern )
.setMaxResults( 50 ) .setMaxResults( 50 )
.list(); .list();
---- ----

View File

@ -64,7 +64,7 @@ Internally Hibernate uses a registry of basic types when it needs to resolve a s
|CharacterArrayNClobType |NCLOB |java.lang.Character[] |N/A |CharacterArrayNClobType |NCLOB |java.lang.Character[] |N/A
|======================================================================================================================================================================================================================================================================================= |=======================================================================================================================================================================================================================================================================================
.BasicTypes added by hibernate-java8 .Java 8 BasicTypes
[cols=",,,",options="header",] [cols=",,,",options="header",]
|================================================================================================= |=================================================================================================
|Hibernate type (org.hibernate.type package) |JDBC type |Java type |BasicTypeRegistry key(s) |Hibernate type (org.hibernate.type package) |JDBC type |Java type |BasicTypeRegistry key(s)
@ -78,13 +78,7 @@ Internally Hibernate uses a registry of basic types when it needs to resolve a s
|OffsetTimeType |TIMESTAMP |java.time.ZonedDateTime |ZonedDateTime, java.time.ZonedDateTime |OffsetTimeType |TIMESTAMP |java.time.ZonedDateTime |ZonedDateTime, java.time.ZonedDateTime
|================================================================================================= |=================================================================================================
[NOTE] .Hibernate Spatial BasicTypes
====
To use these hibernate-java8 types just add the `hibernate-java8` dependency to your classpath and Hibernate will take care of the rest.
See <<basic-datetime>> for more about Java 8 Date/Time types.
====
.BasicTypes added by hibernate-spatial
[cols=",,,",options="header",] [cols=",,,",options="header",]
|================================================================================================= |=================================================================================================
|Hibernate type (org.hibernate.spatial package) |JDBC type |Java type |BasicTypeRegistry key(s) |Hibernate type (org.hibernate.spatial package) |JDBC type |Java type |BasicTypeRegistry key(s)
@ -951,19 +945,6 @@ If the `java.util.Date` marks a point in time, the `java.util.Calendar` takes in
===== Mapping Java 8 Date/Time Values ===== Mapping Java 8 Date/Time Values
Java 8 came with a new Date/Time API, offering support for instant dates, intervals, local and zoned Date/Time immutable instances, bundled in the `java.time` package. Java 8 came with a new Date/Time API, offering support for instant dates, intervals, local and zoned Date/Time immutable instances, bundled in the `java.time` package.
Hibernate added support for the new Date/Time API in a new module, which must be included with the following Maven dependency:
.`hibernate-java8` Maven dependency
====
[source,xml]
----
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>${hibernate.version}</version>
</dependency>
----
====
The mapping between the standard SQL Date/Time types and the supported Java 8 Date/Time class types looks as follows; The mapping between the standard SQL Date/Time types and the supported Java 8 Date/Time class types looks as follows;

View File

@ -15,7 +15,7 @@ Hibernate supports three types of configurations within OSGi.
=== hibernate-osgi === hibernate-osgi
Rather than embed OSGi capabilities into hibernate-core, hibernate-entitymanager, and sub-modules, hibernate-osgi was created. Rather than embed OSGi capabilities into hibernate-core, and sub-modules, hibernate-osgi was created.
It's purposefully separated, isolating all OSGi dependencies. It's purposefully separated, isolating all OSGi dependencies.
It provides an OSGi-specific `ClassLoader` (aggregates the container's `ClassLoader` with core and `EntityManager` `ClassLoader`s), It provides an OSGi-specific `ClassLoader` (aggregates the container's `ClassLoader` with core and `EntityManager` `ClassLoader`s),
JPA persistence provider, `SessionFactory`/`EntityManagerFactory` bootstrapping, entities/mappings scanner, and service management. JPA persistence provider, `SessionFactory`/`EntityManagerFactory` bootstrapping, entities/mappings scanner, and service management.
@ -110,7 +110,7 @@ include::{sourcedir}/blueprint.xml[]
[[osgi-unmanaged-jpa]] [[osgi-unmanaged-jpa]]
=== Unmanaged JPA === Unmanaged JPA
Hibernate also supports the use of JPA through hibernate-entitymanager, unmanaged by the OSGi container. Hibernate also supports the use of JPA, unmanaged by the OSGi container.
The client bundle is responsible for managing the `EntityManagerFactory` and `EntityManager`s. The client bundle is responsible for managing the `EntityManagerFactory` and `EntityManager`s.
=== persistence.xml === persistence.xml

View File

@ -156,6 +156,18 @@ include::{sourcedir}/PersistenceContextTest.java[tags=pc-find-by-id-native-examp
In both cases null is returned if no matching database row was found. In both cases null is returned if no matching database row was found.
It's possible to return a Java 8 `Optional` as well:
[[tag::pc-find-optional-by-id-native-example]]
.Obtaining an Optional entity reference with its data initialized using the `byId()` Hibernate API
====
[source, JAVA, indent=0]
----
include::{sourcedir}/PersistenceContextTest.java[tags=pc-find-optional-by-id-native-example]
----
====
[[pc-find-natural-id]] [[pc-find-natural-id]]
=== Obtain an entity by natural-id === Obtain an entity by natural-id
@ -190,6 +202,17 @@ include::{sourcedir}/PersistenceContextTest.java[tags=pc-find-by-natural-id-exam
---- ----
==== ====
We can also use a Java 8 `Optional` to load an entity by its natural id:
[[pc-find-optional-by-simple-natural-id-example]]
.Load an Optional entity by natural-id
====
[source, JAVA, indent=0]
----
include::{sourcedir}/PersistenceContextTest.java[tags=pc-find-optional-by-simple-natural-id-example]
----
====
Hibernate offer a consistent API for accessing persistent data by identifier or by the natural-id. Each of these defines the same two data access methods: Hibernate offer a consistent API for accessing persistent data by identifier or by the natural-id. Each of these defines the same two data access methods:
getReference:: getReference::

View File

@ -100,18 +100,18 @@ Relying on provider specific hints limits your applications portability to some
Attributes that are not specified are treated as `FetchType.LAZY` or `FetchType.EAGER` depending on the attribute's definition in metadata. Attributes that are not specified are treated as `FetchType.LAZY` or `FetchType.EAGER` depending on the attribute's definition in metadata.
For details, see the EntityGraph discussions in <<chapters/fetching/Fetching.adoc#fetching,Fetching>>. For details, see the EntityGraph discussions in <<chapters/fetching/Fetching.adoc#fetching,Fetching>>.
`org.hibernate.cacheMode`:: `org.hibernate.cacheMode`::
Defines the `CacheMode` to use. See `org.hibernate.Query#setCacheMode`. Defines the `CacheMode` to use. See `org.hibernate.query.Query#setCacheMode`.
`org.hibernate.cacheable`:: `org.hibernate.cacheable`::
Defines whether the query is cacheable. true/false. See `org.hibernate.Query#setCacheable`. Defines whether the query is cacheable. true/false. See `org.hibernate.query.Query#setCacheable`.
`org.hibernate.cacheRegion`:: `org.hibernate.cacheRegion`::
For queries that are cacheable, defines a specific cache region to use. See `org.hibernate.Query#setCacheRegion`. For queries that are cacheable, defines a specific cache region to use. See `org.hibernate.query.Query#setCacheRegion`.
`org.hibernate.comment`:: `org.hibernate.comment`::
Defines the comment to apply to the generated SQL. See `org.hibernate.Query#setComment`. Defines the comment to apply to the generated SQL. See `org.hibernate.query.Query#setComment`.
`org.hibernate.fetchSize`:: `org.hibernate.fetchSize`::
Defines the JDBC fetch-size to use. See `org.hibernate.Query#setFetchSize` Defines the JDBC fetch-size to use. See `org.hibernate.query.Query#setFetchSize`
`org.hibernate.flushMode`:: `org.hibernate.flushMode`::
Defines the Hibernate-specific `FlushMode` to use. See `org.hibernate.Query#setFlushMode.` If possible, prefer using `javax.persistence.Query#setFlushMode` instead. Defines the Hibernate-specific `FlushMode` to use. See `org.hibernate.query.Query#setFlushMode.` If possible, prefer using `javax.persistence.Query#setFlushMode` instead.
`org.hibernate.readOnly`:: Defines that entities and collections loaded by this query should be marked as read-only. See `org.hibernate.Query#setReadOnly` `org.hibernate.readOnly`:: Defines that entities and collections loaded by this query should be marked as read-only. See `org.hibernate.query.Query#setReadOnly`
The final thing that needs to happen before the query can be executed is to bind the values for any defined parameters. The final thing that needs to happen before the query can be executed is to bind the values for any defined parameters.
JPA defines a simplified set of parameter binding methods. JPA defines a simplified set of parameter binding methods.
@ -170,7 +170,7 @@ include::{sourcedir}/HQLTest.java[tags=jpql-api-single-result-example]
[[hql-api]] [[hql-api]]
=== Hibernate Query API === Hibernate Query API
In Hibernate, the HQL query is represented as `org.hibernate.Query` which is obtained from a `Session`. In Hibernate, the HQL query is represented as `org.hibernate.query.Query` which is obtained from a `Session`.
If the HQL is a named query, `Session#getNamedQuery` would be used; otherwise `Session#createQuery` is needed. If the HQL is a named query, `Session#getNamedQuery` would be used; otherwise `Session#createQuery` is needed.
[[hql-api-example]] [[hql-api-example]]
@ -295,6 +295,23 @@ include::{sourcedir}/HQLTest.java[tags=hql-api-list-example]
---- ----
==== ====
Since 5.2, Hibernate offers support for returning a `Stream` which can be later used to transform the underlying `ResultSet`.
[[hql-api-stream-example]]
.Hibernate `stream()` result
====
[source, JAVA, indent=0]
----
include::{sourcedir}/HQLTest.java[tags=hql-api-stream-example]
----
====
[NOTE]
====
Internally, the `stream()` behaves like a `Query#scroll` and the underlying result is backed by a `ScrollableResults`.
For this reason, the `Stream` contains an `Object[]` instead of the actual `Query` result type.
====
[[hql-api-unique-result-example]] [[hql-api-unique-result-example]]
.Hibernate `uniqueResult()` .Hibernate `uniqueResult()`
==== ====
@ -436,7 +453,7 @@ This is a Hibernate specific feature and will not work in a portable manner.
Custom version types, `org.hibernate.usertype.UserVersionType`, are not allowed in conjunction with a `update versioned` statement. Custom version types, `org.hibernate.usertype.UserVersionType`, are not allowed in conjunction with a `update versioned` statement.
==== ====
An `UPDATE` statement is executed using the `executeUpdate()` of either `org.hibernate.Query` or `javax.persistence.Query`. An `UPDATE` statement is executed using the `executeUpdate()` of either `org.hibernate.query.Query` or `javax.persistence.Query`.
The method is named for those familiar with the JDBC `executeUpdate()` on `java.sql.PreparedStatement`. The method is named for those familiar with the JDBC `executeUpdate()` on `java.sql.PreparedStatement`.
The `int` value returned by the `executeUpdate()` method indicates the number of entities effected by the operation. The `int` value returned by the `executeUpdate()` method indicates the number of entities effected by the operation.
@ -476,7 +493,7 @@ include::{extrasdir}/statement_delete_bnf.txt[]
---- ----
==== ====
A `DELETE` statement is also executed using the `executeUpdate()` method of either `org.hibernate.Query` or `javax.persistence.Query`. A `DELETE` statement is also executed using the `executeUpdate()` method of either `org.hibernate.query.Query` or `javax.persistence.Query`.
[[hql-insert]] [[hql-insert]]
=== Insert statements === Insert statements

View File

@ -14,6 +14,8 @@ import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.Query; import javax.persistence.Query;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
@ -667,7 +669,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-example[] //tag::hql-api-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" "where p.name like :name"
@ -681,7 +683,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-named-query-example[] //tag::hql-api-named-query-example[]
org.hibernate.Query query = session.getNamedQuery( "get_person_by_name" ); org.hibernate.query.Query query = session.getNamedQuery( "get_person_by_name" );
//end::hql-api-named-query-example[] //end::hql-api-named-query-example[]
}); });
} }
@ -691,7 +693,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-basic-usage-example[] //tag::hql-api-basic-usage-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" ) "where p.name like :name" )
@ -712,7 +714,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-example[] //tag::hql-api-parameter-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" ) "where p.name like :name" )
@ -726,7 +728,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-inferred-type-example[] //tag::hql-api-parameter-inferred-type-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" ) "where p.name like :name" )
@ -741,13 +743,13 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
Date timestamp = new Date( ); Date timestamp = new Date( );
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-short-form-example[] //tag::hql-api-parameter-short-form-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name " + "where p.name like :name " +
" and p.createdOn > :timestamp" ) " and p.createdOn > :timestamp" )
.setString( "name", "J%" ) .setParameter( "name", "J%" )
.setTimestamp( "timestamp", timestamp ); .setParameter( "timestamp", timestamp, TemporalType.TIMESTAMP);
//end::hql-api-parameter-short-form-example[] //end::hql-api-parameter-short-form-example[]
}); });
} }
@ -758,7 +760,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
Date timestamp = new Date( ); Date timestamp = new Date( );
Session session = entityManager.unwrap( Session.class ); Session session = entityManager.unwrap( Session.class );
//tag::hql-api-positional-parameter-example[] //tag::hql-api-positional-parameter-example[]
org.hibernate.Query query = session.createQuery( org.hibernate.query.Query query = session.createQuery(
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like ? " ) "where p.name like ? " )
@ -776,12 +778,35 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" ) "where p.name like :name" )
.setString( "name", "J%" ) .setParameter( "name", "J%" )
.list(); .list();
//end::hql-api-list-example[] //end::hql-api-list-example[]
}); });
} }
@Test
public void test_hql_api_stream_example() {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-stream-example[]
Stream<Object[]> persons = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.stream();
Map<Phone, List<Call>> callRegistry = persons
.map( row -> Person.class.cast( row[0] ) )
.flatMap( person -> person.getPhones().stream() )
.flatMap( phone -> phone.getCalls().stream() )
.collect(Collectors.groupingBy(Call::getPhone));
//end::hql-api-stream-example[]
assertEquals( 1, callRegistry.size() );
});
}
@Test @Test
public void test_hql_api_unique_result_example() { public void test_hql_api_unique_result_example() {
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {
@ -791,7 +816,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
"select p " + "select p " +
"from Person p " + "from Person p " +
"where p.name like :name" ) "where p.name like :name" )
.setString( "name", "J%" ) .setParameter( "name", "J%" )
.uniqueResult(); .uniqueResult();
//end::hql-api-unique-result-example[] //end::hql-api-unique-result-example[]
}); });

View File

@ -9,6 +9,7 @@ package org.hibernate.userguide.pc;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
@ -132,6 +133,10 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
Person person = session.byId( Person.class ).load( personId ); Person person = session.byId( Person.class ).load( personId );
//end::pc-find-by-id-native-example[] //end::pc-find-by-id-native-example[]
//tag::pc-find-optional-by-id-native-example[]
Optional<Person> optionalPerson = session.byId( Person.class ).loadOptional( personId );
//end::pc-find-optional-by-id-native-example[]
String isbn = "123-456-7890"; String isbn = "123-456-7890";
//tag::pc-find-by-simple-natural-id-example[] //tag::pc-find-by-simple-natural-id-example[]
@ -144,9 +149,19 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
String isbn = "123-456-7890"; String isbn = "123-456-7890";
//tag::pc-find-by-natural-id-example[] //tag::pc-find-by-natural-id-example[]
Book book = session.byNaturalId( Book.class ).using( "isbn", isbn ).load( ); Book book = session
.byNaturalId( Book.class )
.using( "isbn", isbn )
.load( );
//end::pc-find-by-natural-id-example[] //end::pc-find-by-natural-id-example[]
assertNotNull(book); assertNotNull(book);
//tag::pc-find-optional-by-simple-natural-id-example[]
Optional<Book> optionalBook = session
.byNaturalId( Book.class )
.using( "isbn", isbn )
.loadOptional( );
//end::pc-find-optional-by-simple-natural-id-example[]
} ); } );
doInJPA( this::entityManagerFactory, entityManager -> { doInJPA( this::entityManagerFactory, entityManager -> {