/*
* 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.components.joins;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ComponentJoinTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Entity.class, EmbeddedType.class, ManyToOneType.class };
}
public static final String THEVALUE = "thevalue";
@Before
public void before() {
EntityManager entityManager = entityManagerFactory().createEntityManager();
entityManager.getTransaction().begin();
ManyToOneType manyToOneType = new ManyToOneType( THEVALUE );
EmbeddedType embeddedType = new EmbeddedType( manyToOneType );
Entity entity = new Entity( embeddedType );
entityManager.persist( entity );
entityManager.getTransaction().commit();
entityManager.close();
}
@After
public void after() {
EntityManager entityManager = entityManagerFactory().createEntityManager();
entityManager.getTransaction().begin();
entityManager.createQuery( "delete Entity" ).executeUpdate();
entityManager.createQuery( "delete ManyToOneType" ).executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();
}
interface JoinBuilder {
Join<EmbeddedType,ManyToOneType> buildJoinToManyToOneType(Join<Entity, EmbeddedType> source);
}
private void doTest(JoinBuilder joinBuilder) {
EntityManager entityManager = getOrCreateEntityManager();
entityManager.getTransaction().begin();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> criteriaQuery = builder.createTupleQuery();
Root<Entity> root = criteriaQuery.from( Entity.class );
Join<Entity, EmbeddedType> join = root.join( "embeddedType", JoinType.LEFT );
// left join to the manyToOne on the embeddable with a string property
Path<String> path = joinBuilder.buildJoinToManyToOneType( join ).get( "value" );
// select the path in the tuple
criteriaQuery.select( builder.tuple( path ) );
List<Tuple> results = entityManager.createQuery( criteriaQuery ).getResultList();
Tuple result = results.iterator().next();
assertEquals( THEVALUE, result.get(0) );
entityManager.getTransaction().commit();
entityManager.close();
}
@Test
public void getResultWithStringPropertyDerivedPath() {
doTest(
new JoinBuilder() {
@Override
public Join<EmbeddedType, ManyToOneType> buildJoinToManyToOneType(Join<Entity, EmbeddedType> source) {
return source.join( "manyToOneType", JoinType.LEFT );
}
}
);
}
@Test
@SuppressWarnings("unchecked")
public void getResultWithMetamodelDerivedPath() {
doTest(
new JoinBuilder() {
@Override
public Join<EmbeddedType, ManyToOneType> buildJoinToManyToOneType(Join<Entity, EmbeddedType> source) {
final SingularAttribute<EmbeddedType, ManyToOneType> attr =
(SingularAttribute<EmbeddedType, ManyToOneType>) entityManagerFactory().getMetamodel()
.managedType( EmbeddedType.class )
.getDeclaredSingularAttribute( "manyToOneType" );
return source.join( attr, JoinType.LEFT );
}
}
);
}
}