/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.criteria;
import javax.persistence.EntityManager;
import javax.persistence.Parameter;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.Arrays;
import org.junit.Test;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
/**
* @author Steve Ebersole
*/
public class ParameterTest extends BaseEntityManagerFunctionalTestCase {
@Test
public void testPrimitiveArrayParameterBinding() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = em.getCriteriaBuilder()
.createQuery( MultiTypedBasicAttributesEntity.class );
Root<MultiTypedBasicAttributesEntity> rootEntity = criteria.from( MultiTypedBasicAttributesEntity.class );
Path<byte[]> someBytesPath = rootEntity.get( MultiTypedBasicAttributesEntity_.someBytes );
ParameterExpression<byte[]> param = em.getCriteriaBuilder().parameter( byte[].class, "theBytes" );
criteria.where( em.getCriteriaBuilder().equal( someBytesPath, param ) );
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
query.setParameter( param, new byte[] { 1,1,1 } );
assertThat( query.getParameterValue( param.getName() ), instanceOf( byte[].class) );
query.getResultList();
em.getTransaction().commit();
em.close();
}
@Test
public void testNonPrimitiveArrayParameterBinding() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = em.getCriteriaBuilder()
.createQuery( MultiTypedBasicAttributesEntity.class );
Root<MultiTypedBasicAttributesEntity> rootEntity = criteria.from( MultiTypedBasicAttributesEntity.class );
Path<Byte[]> thePath = rootEntity.get( MultiTypedBasicAttributesEntity_.someWrappedBytes );
ParameterExpression<Byte[]> param = em.getCriteriaBuilder().parameter( Byte[].class, "theBytes" );
criteria.where( em.getCriteriaBuilder().equal( thePath, param ) );
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
query.setParameter( param, new Byte[] { Byte.valueOf((byte)1), Byte.valueOf((byte)1), Byte.valueOf((byte)1) } );
assertThat( query.getParameterValue( param.getName() ), instanceOf( Byte[].class ) );
query.getResultList();
em.getTransaction().commit();
em.close();
}
@Test
public void testNamedParameterMetadata() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = em.getCriteriaBuilder()
.createQuery( MultiTypedBasicAttributesEntity.class );
Root<MultiTypedBasicAttributesEntity> rootEntity = criteria.from( MultiTypedBasicAttributesEntity.class );
criteria.where(
em.getCriteriaBuilder().equal(
rootEntity.get( MultiTypedBasicAttributesEntity_.id ),
em.getCriteriaBuilder().parameter( Long.class, "id" )
)
);
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
Parameter parameter = query.getParameter( "id" );
assertEquals( "id", parameter.getName() );
em.getTransaction().commit();
em.close();
}
@Test
public void testParameterInParameterList() {
// Yes, this test makes no semantic sense. But the JPA TCK does it...
// it causes a problem on Derby, which does not like the form "... where ? in (?,?)"
// Derby wants one side or the other to be CAST (I assume so it can check typing).
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = em.getCriteriaBuilder()
.createQuery( MultiTypedBasicAttributesEntity.class );
criteria.from( MultiTypedBasicAttributesEntity.class );
criteria.where(
em.getCriteriaBuilder().in( em.getCriteriaBuilder().parameter( Long.class, "p1" ) )
.value( em.getCriteriaBuilder().parameter( Long.class, "p2" ) )
.value( em.getCriteriaBuilder().parameter( Long.class, "p3" ) )
);
TypedQuery<MultiTypedBasicAttributesEntity> query = em.createQuery( criteria );
query.setParameter( "p1", 1L );
query.setParameter( "p2", 2L );
query.setParameter( "p3", 3L );
query.getResultList();
em.getTransaction().commit();
em.close();
}
@Test
@TestForIssue(jiraKey = "HHH-10870")
public void testParameterInParameterList2() {
TransactionUtil.doInJPA( this::entityManagerFactory, em -> {
final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
final CriteriaQuery<MultiTypedBasicAttributesEntity> criteria = criteriaBuilder
.createQuery( MultiTypedBasicAttributesEntity.class );
final ParameterExpression<Iterable> parameter = criteriaBuilder.parameter( Iterable.class );
final Root<MultiTypedBasicAttributesEntity> root = criteria.from( MultiTypedBasicAttributesEntity.class );
criteria.select( root ).where( root.get( "id" ).in( parameter ) );
final TypedQuery<MultiTypedBasicAttributesEntity> query1 = em.createQuery( criteria );
query1.setParameter( parameter, Arrays.asList( 1L, 2L, 3L ) );
query1.getResultList();
} );
}
@Override
public Class[] getAnnotatedClasses() {
return new Class[] { MultiTypedBasicAttributesEntity.class };
}
}