HHH-11176: Add support for Tuple results for native queries
This commit is contained in:
parent
1347ee6250
commit
68a40425b1
|
@ -61,6 +61,7 @@ import org.hibernate.engine.transaction.internal.TransactionImpl;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||||
import org.hibernate.id.uuid.StandardRandomStrategy;
|
import org.hibernate.id.uuid.StandardRandomStrategy;
|
||||||
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
|
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
|
||||||
|
import org.hibernate.jpa.spi.NativeQueryTupleTransformer;
|
||||||
import org.hibernate.jpa.spi.TupleBuilderTransformer;
|
import org.hibernate.jpa.spi.TupleBuilderTransformer;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
|
@ -781,7 +782,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess", "unchecked"})
|
@SuppressWarnings({"WeakerAccess", "unchecked"})
|
||||||
protected <T> NativeQueryImplementor createNativeQuery(NamedSQLQueryDefinition queryDefinition, Class<T> resultType) {
|
protected <T> NativeQueryImplementor createNativeQuery(NamedSQLQueryDefinition queryDefinition, Class<T> resultType) {
|
||||||
if ( resultType != null ) {
|
if ( resultType != null && !Tuple.class.equals(resultType)) {
|
||||||
resultClassChecking( resultType, queryDefinition );
|
resultClassChecking( resultType, queryDefinition );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,6 +791,9 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
this,
|
this,
|
||||||
factory.getQueryPlanCache().getSQLParameterMetadata( queryDefinition.getQueryString(), false )
|
factory.getQueryPlanCache().getSQLParameterMetadata( queryDefinition.getQueryString(), false )
|
||||||
);
|
);
|
||||||
|
if (Tuple.class.equals(resultType)) {
|
||||||
|
query.setResultTransformer(new NativeQueryTupleTransformer());
|
||||||
|
}
|
||||||
query.setHibernateFlushMode( queryDefinition.getFlushMode() );
|
query.setHibernateFlushMode( queryDefinition.getFlushMode() );
|
||||||
query.setComment( queryDefinition.getComment() != null ? queryDefinition.getComment() : queryDefinition.getName() );
|
query.setComment( queryDefinition.getComment() != null ? queryDefinition.getComment() : queryDefinition.getName() );
|
||||||
if ( queryDefinition.getLockOptions() != null ) {
|
if ( queryDefinition.getLockOptions() != null ) {
|
||||||
|
@ -876,7 +880,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
|
|
||||||
try {
|
try {
|
||||||
NativeQueryImplementor query = createNativeQuery( sqlString );
|
NativeQueryImplementor query = createNativeQuery( sqlString );
|
||||||
query.addEntity( "alias1", resultClass.getName(), LockMode.READ );
|
handleNativeQueryResult(query, resultClass);
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
catch ( RuntimeException he ) {
|
catch ( RuntimeException he ) {
|
||||||
|
@ -884,6 +888,14 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleNativeQueryResult(NativeQueryImplementor query, Class resultClass) {
|
||||||
|
if (Tuple.class.equals(resultClass)) {
|
||||||
|
query.setResultTransformer(new NativeQueryTupleTransformer());
|
||||||
|
} else {
|
||||||
|
query.addEntity( "alias1", resultClass.getName(), LockMode.READ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) {
|
public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
|
|
|
@ -140,6 +140,7 @@ public class CriteriaQueryTupleTransformer extends BasicTransformerAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
|
// todo : make a copy?
|
||||||
return tuples;
|
return tuples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package org.hibernate.jpa.spi;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
import javax.persistence.TupleElement;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.transform.BasicTransformerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResultTransformer adapter for handling Tuple results from Native queries
|
||||||
|
*
|
||||||
|
* @author Arnold Galovics
|
||||||
|
*/
|
||||||
|
public class NativeQueryTupleTransformer extends BasicTransformerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object transformTuple(Object[] tuple, String[] aliases) {
|
||||||
|
return new NativeTupleImpl( tuple, aliases );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NativeTupleElementImpl<X> implements TupleElement<X> {
|
||||||
|
|
||||||
|
private final Class<? extends X> javaType;
|
||||||
|
|
||||||
|
private final String alias;
|
||||||
|
|
||||||
|
public NativeTupleElementImpl(Class<? extends X> javaType, String alias) {
|
||||||
|
this.javaType = javaType;
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends X> getJavaType() {
|
||||||
|
return javaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NativeTupleImpl implements Tuple {
|
||||||
|
|
||||||
|
private Object[] tuple;
|
||||||
|
|
||||||
|
private Map<String, Object> aliasToValue = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public NativeTupleImpl(Object[] tuple, String[] aliases) {
|
||||||
|
if ( tuple == null || aliases == null || tuple.length != aliases.length ) {
|
||||||
|
throw new HibernateException( "Got different size of tuples and aliases" );
|
||||||
|
}
|
||||||
|
this.tuple = tuple;
|
||||||
|
for ( int i = 0; i < tuple.length; i++ ) {
|
||||||
|
aliasToValue.put( aliases[i].toLowerCase(), tuple[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X get(String alias, Class<X> type) {
|
||||||
|
final Object untyped = get( alias );
|
||||||
|
|
||||||
|
return ( untyped != null ) ? type.cast( untyped ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(String alias) {
|
||||||
|
Object tupleElement = aliasToValue.get( alias.toLowerCase() );
|
||||||
|
|
||||||
|
if ( tupleElement == null ) {
|
||||||
|
throw new IllegalArgumentException( "Unknown alias [" + alias + "]" );
|
||||||
|
}
|
||||||
|
return tupleElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X get(int i, Class<X> type) {
|
||||||
|
final Object untyped = get( i );
|
||||||
|
|
||||||
|
return ( untyped != null ) ? type.cast( untyped ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(int i) {
|
||||||
|
if ( i < 0 ) {
|
||||||
|
throw new IllegalArgumentException( "requested tuple index must be greater than zero" );
|
||||||
|
}
|
||||||
|
if ( i >= aliasToValue.size() ) {
|
||||||
|
throw new IllegalArgumentException( "requested tuple index exceeds actual tuple size" );
|
||||||
|
}
|
||||||
|
return tuple[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
// todo : make a copy?
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TupleElement<?>> getElements() {
|
||||||
|
List<TupleElement<?>> elements = new ArrayList<>( aliasToValue.size() );
|
||||||
|
|
||||||
|
for ( Map.Entry<String, Object> entry : aliasToValue.entrySet() ) {
|
||||||
|
elements.add( new NativeTupleElementImpl<>( entry.getValue().getClass(), entry.getKey() ) );
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> X get(TupleElement<X> tupleElement) {
|
||||||
|
return get( tupleElement.getAlias(), tupleElement.getJavaType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,406 @@
|
||||||
|
package org.hibernate.jpa.test.query;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import javax.persistence.criteria.CriteriaDelete;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class TupleNativeQueryTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[]{User.class};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
User user = new User("Arnold");
|
||||||
|
entityManager.persist(user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
CriteriaDelete<User> delete = entityManager.getCriteriaBuilder().createCriteriaDelete(User.class);
|
||||||
|
delete.from(User.class);
|
||||||
|
entityManager.createQuery(delete).executeUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionalGetterShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get(0));
|
||||||
|
assertEquals("Arnold", tuple.get(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionalGetterWithClassShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get(0, BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get(1, String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterShouldThrowExceptionWhenLessThanZeroGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithClassShouldThrowExceptionWhenLessThanZeroGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterShouldThrowExceptionWhenTupleSizePositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithClassShouldThrowExceptionWhenTupleSizePositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterShouldThrowExceptionWhenExceedingPositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithClassShouldThrowExceptionWhenExceedingPositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithoutExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ID"));
|
||||||
|
assertEquals("Arnold", tuple.get("FIRSTNAME"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testAliasGetterShouldWorkWithoutExplicitAliasWhenLowerCaseAliasGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get("id");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testAliasGetterShouldThrowExceptionWithoutExplicitAliasWhenWrongAliasGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get("e");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithClassWithoutExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ID", BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get("FIRSTNAME", String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleAliasedResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ALIAS1"));
|
||||||
|
assertEquals("Arnold", tuple.get("ALIAS2"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithClassWithExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = getTupleAliasedResult(entityManager);
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ALIAS1", BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get("ALIAS2", String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToArrayShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> tuples = getTupleResult(entityManager);
|
||||||
|
Object[] result = tuples.get(0).toArray();
|
||||||
|
assertArrayEquals(new Object[]{BigInteger.ONE, "Arnold"}, result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetElementsShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> tuples = getTupleResult(entityManager);
|
||||||
|
List<TupleElement<?>> result = tuples.get(0).getElements();
|
||||||
|
assertEquals(2, result.size());
|
||||||
|
assertEquals(BigInteger.class, result.get(0).getJavaType());
|
||||||
|
assertEquals("id", result.get(0).getAlias());
|
||||||
|
assertEquals(String.class, result.get(1).getJavaType());
|
||||||
|
assertEquals("firstname", result.get(1).getAlias());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get(0));
|
||||||
|
assertEquals("Arnold", tuple.get(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryWithClassShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get(0, BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get(1, String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryShouldThrowExceptionWhenLessThanZeroGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryWithClassShouldThrowExceptionWhenLessThanZeroGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryShouldThrowExceptionWhenTupleSizePositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryWithClassShouldThrowExceptionWhenTupleSizePositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryShouldThrowExceptionWhenExceedingPositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPositionalGetterWithNamedNativeQueryWithClassShouldThrowExceptionWhenExceedingPositionGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get(3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithNamedNativeQueryWithoutExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ID"));
|
||||||
|
assertEquals("Arnold", tuple.get("FIRSTNAME"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testAliasGetterWithNamedNativeQueryShouldWorkWithoutExplicitAliasWhenLowerCaseAliasGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get("id");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testAliasGetterWithNamedNativeQueryShouldThrowExceptionWithoutExplicitAliasWhenWrongAliasGiven() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
tuple.get("e");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithNamedNativeQueryWithClassWithoutExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ID", BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get("FIRSTNAME", String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithNamedNativeQueryWithExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard_with_alias", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ALIAS1"));
|
||||||
|
assertEquals("Arnold", tuple.get("ALIAS2"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAliasGetterWithNamedNativeQueryWithClassWithExplicitAliasShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> result = entityManager.createNamedQuery("standard_with_alias", Tuple.class).getResultList();
|
||||||
|
Tuple tuple = result.get(0);
|
||||||
|
assertEquals(BigInteger.ONE, tuple.get("ALIAS1", BigInteger.class));
|
||||||
|
assertEquals("Arnold", tuple.get("ALIAS2", String.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToArrayShouldWithNamedNativeQueryWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> tuples = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
Object[] result = tuples.get(0).toArray();
|
||||||
|
assertArrayEquals(new Object[]{BigInteger.ONE, "Arnold"}, result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetElementsWithNamedNativeQueryShouldWorkProperly() {
|
||||||
|
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> tuples = entityManager.createNamedQuery("standard", Tuple.class).getResultList();
|
||||||
|
List<TupleElement<?>> result = tuples.get(0).getElements();
|
||||||
|
assertEquals(2, result.size());
|
||||||
|
assertEquals(BigInteger.class, result.get(0).getJavaType());
|
||||||
|
assertEquals("id", result.get(0).getAlias());
|
||||||
|
assertEquals(String.class, result.get(1).getJavaType());
|
||||||
|
assertEquals("firstname", result.get(1).getAlias());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Tuple> getTupleAliasedResult(EntityManager entityManager) {
|
||||||
|
Query query = entityManager.createNativeQuery("SELECT id AS alias1, firstname AS alias2 FROM users", Tuple.class);
|
||||||
|
return (List<Tuple>) query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Tuple> getTupleResult(EntityManager entityManager) {
|
||||||
|
Query query = entityManager.createNativeQuery("SELECT id, firstname FROM users", Tuple.class);
|
||||||
|
return (List<Tuple>) query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "users")
|
||||||
|
@NamedNativeQueries({
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "standard",
|
||||||
|
query = "SELECT id, firstname FROM users"
|
||||||
|
),
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "standard_with_alias",
|
||||||
|
query = "SELECT id AS alias1, firstname AS alias2 FROM users"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
public static class User {
|
||||||
|
@Id
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String firstName) {
|
||||||
|
this.id = 1L;
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue