HHH-10824 - Fix query stream API to support returning R rather than Object[] when selecting one type.

This commit is contained in:
Chris Cranford 2016-06-11 21:34:31 -05:00
parent e9b48a881d
commit e2343f873a
5 changed files with 57 additions and 3 deletions

View File

@ -790,7 +790,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
Session session = entityManager.unwrap( Session.class );
//tag::hql-api-stream-example[]
Stream<Object[]> persons = session.createQuery(
Stream<Person> persons = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
@ -798,7 +798,6 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
.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));

View File

@ -121,6 +121,11 @@ public abstract class AbstractScrollableResults implements ScrollableResultsImpl
return this.closed;
}
@Override
public int getNumberOfTypes() {
return this.types.length;
}
@Override
public final Object[] get() throws HibernateException {
if ( closed ) {

View File

@ -36,6 +36,11 @@ class ScrollableResultsIterator<T> implements CloseableIterator {
@Override
@SuppressWarnings("unchecked")
public T next() {
return (T) scrollableResults.get();
if ( scrollableResults.getNumberOfTypes() == 1 ) {
return (T) scrollableResults.get()[0];
}
else {
return (T) scrollableResults.get();
}
}
}

View File

@ -17,4 +17,5 @@ import org.hibernate.ScrollableResults;
@Incubating
public interface ScrollableResultsImplementor extends ScrollableResults {
boolean isClosed();
int getNumberOfTypes();
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.test.stream.basic;
import java.util.Optional;
import java.util.stream.Stream;
import javax.persistence.Entity;
import javax.persistence.Id;
@ -15,11 +16,15 @@ import org.hibernate.Session;
import org.hibernate.boot.MetadataSources;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.query.Query;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertNotNull;
/**
* @author Steve Ebersole
@ -50,6 +55,45 @@ public class BasicStreamTest extends BaseNonConfigCoreFunctionalTestCase {
session.close();
}
@Test
@TestForIssue(jiraKey = "HHH-10824")
public void testQueryStream() {
Session session = openSession();
try {
session.getTransaction().begin();
MyEntity e= new MyEntity();
e.id = 1;
e.name = "Test";
session.persist( e );
session.getTransaction().commit();
session.clear();
// Test stream query without type.
Object result = session.createQuery( "From MyEntity" ).stream().findFirst().orElse( null );
assertTyping( MyEntity.class, result );
// Test stream query with type.
result = session.createQuery( "From MyEntity", MyEntity.class ).stream().findFirst().orElse( null );
assertTyping( MyEntity.class, result );
// Test stream query using forEach
session.createQuery( "From MyEntity", MyEntity.class ).stream().forEach( i -> {
assertTyping( MyEntity.class, i );
} );
Stream<Object[]> data = session.createQuery( "SELECT me.id, me.name FROM MyEntity me" ).stream();
data.forEach( i -> {
assertTyping( Integer.class, i[0] );
assertTyping( String.class, i[1] );
});
}
finally {
session.close();
}
}
@Entity(name = "MyEntity")
@Table(name="MyEntity")
public static class MyEntity {