Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into wip/6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 committed Mar 3, 2020
2 parents c9190e4 + 5bf772c commit abe1e65
Show file tree
Hide file tree
Showing 53 changed files with 3,784 additions and 227 deletions.
Expand Up @@ -26,7 +26,7 @@ Generally, this required their users to configure the Hibernate dialect or defin
Starting with version 3.2, Hibernate introduced the notion of automatically detecting the dialect to use based on the `java.sql.DatabaseMetaData` obtained from a `java.sql.Connection` to that database.
This was much better, except that this resolution was limited to databases Hibernate know about ahead of time and was in no way configurable or overrideable.

Starting with version 3.3, Hibernate has a fare more powerful way to automatically determine which dialect to be used by relying on a series of delegates which implement the `org.hibernate.dialect.resolver.DialectResolver` which defines only a single method:
Starting with version 3.3, Hibernate has a far more powerful way to automatically determine which dialect to be used by relying on a series of delegates which implement the `org.hibernate.dialect.resolver.DialectResolver` which defines only a single method:

[source,java]
----
Expand Down
Expand Up @@ -165,9 +165,10 @@ include::{sourcedir}/HQLTest.java[tags=jpql-api-positional-parameter-example]
It's good practice not to mix parameter binding forms in a given query.
====

In terms of execution, JPA `Query` offers 2 different methods for retrieving a result set.
In terms of execution, JPA `Query` offers 3 different methods for retrieving a result set.

* `Query#getResultList()` - executes the select query and returns back the list of results.
* `Query#getResultStream()` - executes the select query and returns back a `Stream` over the results.
* `Query#getSingleResult()` - executes the select query and returns a single result. If there were more than one result an exception is thrown.

[[jpql-api-list-example]]
Expand All @@ -179,6 +180,15 @@ include::{sourcedir}/HQLTest.java[tags=jpql-api-list-example]
----
====

[[jpql-api-stream-example]]
.JPA `getResultStream()` result
====
[source, JAVA, indent=0]
----
include::{sourcedir}/HQLTest.java[tags=jpql-api-stream-example]
----
====

[[jpql-api-unique-result-example]]
.JPA `getSingleResult()`
====
Expand Down Expand Up @@ -414,6 +424,29 @@ include::{sourcedir}/HQLTest.java[tags=hql-api-stream-example]
Just like with `ScrollableResults`, you should always close a Hibernate `Stream` either explicitly or using a https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html[try-with-resources] block.
====

[[jpql-api-stream]]
==== Query streaming

Since version 2.2, the JPA `Query` interface offers support for returning a `Stream` via the `getResultStream` method.

Just like the `scroll` method, you can use a try-with-resources block to close the `Stream`
prior to closing the currently running Persistence Context.

Since Hibernate 5.4, the `Stream` is also closed when calling a terminal operation,
as illustrated by the following example.

[[jpql-api-stream-terminal-operation]]
====
[source, JAVA, indent=0]
----
include::{sourcedir}/HQLTest.java[tags=jpql-api-stream-terminal-operation]
----
====

The `Stream` is closed automatically after calling the `collect` method,
since there is no reason to keep the underlying JDBC `ResultSet` open
if the `Stream` cannot be reused.

[[hql-case-sensitivity]]
=== Case Sensitivity

Expand Down
Expand Up @@ -10,7 +10,6 @@
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -43,7 +42,6 @@
import org.hibernate.userguide.model.WireTransferPayment;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
Expand Down Expand Up @@ -673,6 +671,38 @@ public void test_jpql_api_list_example() {
});
}

@Test
public void test_jpql_api_stream_example() {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::jpql-api-stream-example[]
try(Stream<Person> personStream = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name", Person.class )
.setParameter( "name", "J%" )
.getResultStream()) {
List<Person> persons = personStream
.skip( 5 )
.limit( 5 )
.collect( Collectors.toList() );
}
//end::jpql-api-stream-example[]

// tag::jpql-api-stream-terminal-operation[]
List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name", Person.class )
.setParameter( "name", "J%" )
.getResultStream()
.skip( 5 )
.limit( 5 )
.collect( Collectors.toList() );

//end::jpql-api-stream-terminal-operation[]
});
}

@Test
public void test_jpql_api_single_result_example() {
doInJPA( this::entityManagerFactory, entityManager -> {
Expand Down
Expand Up @@ -691,7 +691,7 @@ public SequenceSupport getSequenceSupport() {

@Override
public String getQuerySequencesString() {
return "select * from all_sequences";
return "select * from user_sequences";
}

public SequenceInformationExtractor getSequenceInformationExtractor() {
Expand Down
Expand Up @@ -46,9 +46,9 @@ public ResultSetReturnImpl(JdbcCoordinator jdbcCoordinator, JdbcServices jdbcSer
@Override
public ResultSet extract(PreparedStatement statement) {
// IMPL NOTE : SQL logged by caller
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
final ResultSet rs;
Expand All @@ -58,7 +58,7 @@ public ResultSet extract(PreparedStatement statement) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( statement, executeStart );
sqlStatementLogger.logSlowQuery( statement, executeStartNanos );
}
postExtract( rs, statement );
return rs;
Expand All @@ -79,9 +79,9 @@ private void jdbcExecuteStatementStart() {
@Override
public ResultSet extract(CallableStatement callableStatement) {
// IMPL NOTE : SQL logged by caller
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
final ResultSet rs;
Expand All @@ -91,7 +91,7 @@ public ResultSet extract(CallableStatement callableStatement) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( callableStatement, executeStart );
sqlStatementLogger.logSlowQuery( callableStatement, executeStartNanos );
}
postExtract( rs, callableStatement );
return rs;
Expand All @@ -104,9 +104,9 @@ public ResultSet extract(CallableStatement callableStatement) {
@Override
public ResultSet extract(Statement statement, String sql) {
sqlStatementLogger.logStatement( sql );
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
final ResultSet rs;
Expand All @@ -116,7 +116,7 @@ public ResultSet extract(Statement statement, String sql) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( sql, executeStart );
sqlStatementLogger.logSlowQuery( sql, executeStartNanos );
}
postExtract( rs, statement );
return rs;
Expand All @@ -129,9 +129,9 @@ public ResultSet extract(Statement statement, String sql) {
@Override
public ResultSet execute(PreparedStatement statement) {
// sql logged by StatementPreparerImpl
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
final ResultSet rs;
Expand All @@ -146,7 +146,7 @@ public ResultSet execute(PreparedStatement statement) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( statement, executeStart );
sqlStatementLogger.logSlowQuery( statement, executeStartNanos );
}
postExtract( rs, statement );
return rs;
Expand All @@ -159,9 +159,9 @@ public ResultSet execute(PreparedStatement statement) {
@Override
public ResultSet execute(Statement statement, String sql) {
sqlStatementLogger.logStatement( sql );
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
final ResultSet rs;
Expand All @@ -176,7 +176,7 @@ public ResultSet execute(Statement statement, String sql) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( statement, executeStart );
sqlStatementLogger.logSlowQuery( statement, executeStartNanos );
}
postExtract( rs, statement );
return rs;
Expand All @@ -188,9 +188,9 @@ public ResultSet execute(Statement statement, String sql) {

@Override
public int executeUpdate(PreparedStatement statement) {
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
jdbcExecuteStatementStart();
Expand All @@ -201,16 +201,16 @@ public int executeUpdate(PreparedStatement statement) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( statement, executeStart );
sqlStatementLogger.logSlowQuery( statement, executeStartNanos );
}
}

@Override
public int executeUpdate(Statement statement, String sql) {
sqlStatementLogger.logStatement( sql );
long executeStart = 0;
long executeStartNanos = 0;
if ( this.sqlStatementLogger.getLogSlowQuery() > 0 ) {
executeStart = System.currentTimeMillis();
executeStartNanos = System.nanoTime();
}
try {
jdbcExecuteStatementStart();
Expand All @@ -221,7 +221,7 @@ public int executeUpdate(Statement statement, String sql) {
}
finally {
jdbcExecuteStatementEnd();
sqlStatementLogger.logSlowQuery( statement, executeStart );
sqlStatementLogger.logSlowQuery( statement, executeStartNanos );
}
}

Expand Down
Expand Up @@ -7,6 +7,7 @@
package org.hibernate.engine.jdbc.spi;

import java.sql.Statement;
import java.util.concurrent.TimeUnit;

import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.hibernate.engine.jdbc.internal.Formatter;
Expand Down Expand Up @@ -134,34 +135,34 @@ public void logStatement(String statement, Formatter formatter) {
* Log a slow SQL query
*
* @param statement SQL statement.
* @param startTime Start time in milliseconds.
* @param startTimeNanos Start time in nanoseconds.
*/
public void logSlowQuery(Statement statement, long startTime) {
public void logSlowQuery(Statement statement, long startTimeNanos) {
if ( logSlowQuery < 1 ) {
return;
}
logSlowQuery( statement.toString(), startTime );
logSlowQuery( statement.toString(), startTimeNanos );
}

/**
* Log a slow SQL query
*
* @param sql The SQL query.
* @param startTime Start time in milliseconds.
* @param startTimeNanos Start time in nanoseconds.
*/
@AllowSysOut
public void logSlowQuery(String sql, long startTime) {
public void logSlowQuery(String sql, long startTimeNanos) {
if ( logSlowQuery < 1 ) {
return;
}
assert startTime > 0 : "startTime is invalid!";

long spent = System.currentTimeMillis() - startTime;
if ( startTimeNanos <= 0 ) {
throw new IllegalArgumentException( "startTimeNanos [" + startTimeNanos + "] should be greater than 0!" );
}

assert spent >= 0 : "startTime is invalid!";
long queryExecutionMillis = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTimeNanos );

if ( spent > logSlowQuery ) {
String logData = "SlowQuery: " + spent + " milliseconds. SQL: '" + sql + "'";
if ( queryExecutionMillis > logSlowQuery ) {
String logData = "SlowQuery: " + queryExecutionMillis + " milliseconds. SQL: '" + sql + "'";
LOG_SLOW.info( logData );
if ( logToStdout ) {
System.out.println( logData );
Expand Down
Expand Up @@ -979,7 +979,7 @@ public Object immediateLoad(String entityName, Object id) throws HibernateExcept
}

@Override
public final Object internalLoad(
public Object internalLoad(
String entityName,
Object id,
boolean eager,
Expand Down
Expand Up @@ -347,6 +347,25 @@ public static Constructor getConstructor(Class clazz, Type[] types) throws Prope

}

public static <T> Constructor<T> getConstructor(
Class<T> clazz,
Class... constructorArgs) {
Constructor<T> constructor = null;
try {
constructor = clazz.getDeclaredConstructor( constructorArgs );
try {
ReflectHelper.ensureAccessibility( constructor );
}
catch ( SecurityException e ) {
constructor = null;
}
}
catch ( NoSuchMethodException ignore ) {
}

return constructor;
}

public static Method getMethod(Class clazz, Method method) {
try {
return clazz.getMethod( method.getName(), method.getParameterTypes() );
Expand All @@ -356,6 +375,15 @@ public static Method getMethod(Class clazz, Method method) {
}
}

public static Method getMethod(Class clazz, String methodName, Class... paramTypes) {
try {
return clazz.getMethod( methodName, paramTypes );
}
catch (Exception e) {
return null;
}
}

public static Field findField(Class containerClass, String propertyName) {
if ( containerClass == null ) {
throw new IllegalArgumentException( "Class on which to find field [" + propertyName + "] cannot be null" );
Expand Down

0 comments on commit abe1e65

Please sign in to comment.