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(':hibernate-testing') )
// testCompile( project(path: ':hibernate-entitymanager', configuration: 'tests') )
testRuntime( libraries.h2 )
testRuntime( libraries.hsqldb )

View File

@ -28,7 +28,7 @@ In this case, you do _not_ need to call `addEntity()` anymore.
----
List people = session
.getNamedQuery( "persons" )
.setString( "namePattern", namePattern )
.setParameter( "namePattern", namePattern )
.setMaxResults( 50 )
.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
|=======================================================================================================================================================================================================================================================================================
.BasicTypes added by hibernate-java8
.Java 8 BasicTypes
[cols=",,,",options="header",]
|=================================================================================================
|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
|=================================================================================================
[NOTE]
====
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
.Hibernate Spatial BasicTypes
[cols=",,,",options="header",]
|=================================================================================================
|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
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;

View File

@ -15,7 +15,7 @@ Hibernate supports three types of configurations within 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 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.
@ -110,7 +110,7 @@ include::{sourcedir}/blueprint.xml[]
[[osgi-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.
=== 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.
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]]
=== 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:
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.
For details, see the EntityGraph discussions in <<chapters/fetching/Fetching.adoc#fetching,Fetching>>.
`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`::
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`::
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`::
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`::
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`::
Defines the Hibernate-specific `FlushMode` to use. See `org.hibernate.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`
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.Query#setReadOnly`
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.
@ -170,7 +170,7 @@ include::{sourcedir}/HQLTest.java[tags=jpql-api-single-result-example]
[[hql-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.
[[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]]
.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.
====
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 `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]]
=== Insert statements

View File

@ -14,6 +14,8 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.FlushModeType;
import javax.persistence.Query;
import javax.persistence.TemporalType;
@ -667,7 +669,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
@ -681,7 +683,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//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[]
});
}
@ -691,7 +693,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-basic-usage-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
@ -712,7 +714,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
@ -726,7 +728,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-inferred-type-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
@ -741,13 +743,13 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
Date timestamp = new Date( );
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-parameter-short-form-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name " +
" and p.createdOn > :timestamp" )
.setString( "name", "J%" )
.setTimestamp( "timestamp", timestamp );
.setParameter( "name", "J%" )
.setParameter( "timestamp", timestamp, TemporalType.TIMESTAMP);
//end::hql-api-parameter-short-form-example[]
});
}
@ -758,7 +760,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
Date timestamp = new Date( );
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-positional-parameter-example[]
org.hibernate.Query query = session.createQuery(
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like ? " )
@ -776,12 +778,35 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
"select p " +
"from Person p " +
"where p.name like :name" )
.setString( "name", "J%" )
.setParameter( "name", "J%" )
.list();
//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
public void test_hql_api_unique_result_example() {
doInJPA( this::entityManagerFactory, entityManager -> {
@ -791,7 +816,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
"select p " +
"from Person p " +
"where p.name like :name" )
.setString( "name", "J%" )
.setParameter( "name", "J%" )
.uniqueResult();
//end::hql-api-unique-result-example[]
});

View File

@ -9,6 +9,7 @@ package org.hibernate.userguide.pc;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@ -132,6 +133,10 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
Person person = session.byId( Person.class ).load( personId );
//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";
//tag::pc-find-by-simple-natural-id-example[]
@ -144,9 +149,19 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
String isbn = "123-456-7890";
//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[]
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 -> {