fix the javadoc of Query.getSingleResult()

which incorrectly described the semantics of this method

and add tests for this stuff, since we didn't seem to have them
This commit is contained in:
Gavin King 2021-12-28 19:12:22 +01:00
parent 0b2a357670
commit 553688ca67
5 changed files with 56 additions and 7 deletions

View File

@ -160,15 +160,14 @@ public interface Query<R> extends TypedQuery<R>, CommonQueryContract {
/**
* Convenience method to return a single instance that matches
* the query, or {@code null} if the query returns no results.
* the query, throwing an exception if the query returns no results.
*
* @return the single result or <tt>null</tt>
* @return the single result
*
* @throws NonUniqueResultException if there is more than one matching result
* @throws jakarta.persistence.NonUniqueResultException if there is more than one matching result
* @throws jakarta.persistence.NoResultException if there is no result to return
*/
default R getSingleResult() {
return uniqueResult();
}
R getSingleResult();
/**
* Convenience method to return a single instance that matches

View File

@ -1487,7 +1487,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
public R getSingleResult() {
try {
final List<R> list = list();
if ( list.size() == 0 ) {
if ( list.isEmpty() ) {
throw new NoResultException( "No entity found for query" );
}
return uniqueElement( list );

View File

@ -55,6 +55,11 @@ interface ExceptionExpectations {
assertThat( e.getCause(), instanceOf( SemanticException.class ) );
}
@Override
public void onUniqueResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( org.hibernate.NonUniqueResultException.class ) );
}
@Override
public void onGetSingleResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( jakarta.persistence.NonUniqueResultException.class ) );
@ -133,6 +138,11 @@ interface ExceptionExpectations {
assertThat( e, instanceOf( SemanticException.class ) );
}
@Override
public void onUniqueResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( org.hibernate.NonUniqueResultException.class ) );
}
@Override
public void onGetSingleResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( org.hibernate.NonUniqueResultException.class ) );
@ -208,6 +218,11 @@ interface ExceptionExpectations {
assertThat( e.getCause(), instanceOf( SemanticException.class ) );
}
@Override
public void onUniqueResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( org.hibernate.NonUniqueResultException.class ) );
}
@Override
public void onGetSingleResultWithMultipleResults(RuntimeException e) {
assertThat( e, instanceOf( jakarta.persistence.NonUniqueResultException.class ) );
@ -266,6 +281,8 @@ interface ExceptionExpectations {
void onInvalidQueryExecuted(RuntimeException e);
void onUniqueResultWithMultipleResults(RuntimeException e);
void onGetSingleResultWithMultipleResults(RuntimeException e);
void onGetSingleResultWithNoResults(RuntimeException e);

View File

@ -63,6 +63,19 @@ public class QueryExceptionHandlingTest extends BaseExceptionHandlingTest {
}
}
@Test
public void testUniqueResultWithMultipleResults() {
try {
TransactionUtil2.inSession( sessionFactory(), s -> {
s.createQuery( "from A where id in (1, 2)" ).uniqueResult();
} );
fail( "should have thrown an exception" );
}
catch (RuntimeException expected) {
exceptionExpectations.onUniqueResultWithMultipleResults( expected );
}
}
@Test
@TestForIssue(jiraKey = "HHH-13300")
public void testGetSingleResultWithMultipleResults() {

View File

@ -16,6 +16,7 @@ import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
import jakarta.persistence.EntityManager;
import jakarta.persistence.NoResultException;
import jakarta.persistence.NonUniqueResultException;
import jakarta.persistence.Parameter;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.Query;
@ -1512,4 +1513,23 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
entityManager.close();
}
}
@Test
public void testGetSingleResultWithManyResultsException() {
final EntityManager entityManager = getOrCreateEntityManager();
try {
entityManager.getTransaction().begin();
entityManager.persist( new Item( "1", "1" ) );
entityManager.persist( new Item( "2", "2" ) );
entityManager.createQuery( "FROM Item" ).getSingleResult();
fail( "Expected NoResultException" );
}
catch ( Exception e ) {
assertTyping( NonUniqueResultException.class, e );
}
finally {
entityManager.getTransaction().rollback();
entityManager.close();
}
}
}