View Javadoc
1   package myorg.queryex.criteria;
2   
3   import java.util.Date;
4   import java.util.GregorianCalendar;
5   import java.util.List;
6   
7   import javax.persistence.EntityManager;
8   import javax.persistence.TypedQuery;
9   import javax.persistence.criteria.CriteriaBuilder;
10  import javax.persistence.criteria.CriteriaQuery;
11  import javax.persistence.criteria.Join;
12  import javax.persistence.criteria.Root;
13  import javax.persistence.metamodel.Attribute;
14  import javax.persistence.metamodel.EntityType;
15  
16  import myorg.queryex.Movie;
17  import myorg.queryex.MovieRating;
18  import myorg.queryex.Movie_;
19  import myorg.queryex.QueryBase;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.junit.After;
24  import org.junit.Before;
25  import org.junit.Test;
26  
27  public class MetaModelTest extends QueryBase {
28  	private static final Log log = LogFactory.getLog(MetaModelTest.class);
29  	private EntityManager em2; //second persistence context for parallel queries
30  	
31  	@Before
32  	public void init() {
33  		if (emf!=null) {
34  			em2=emf.createEntityManager();
35  		}
36  	}
37  	
38  	@After
39  	public void destroy() {
40  		destroy(em2);
41  	}
42  	
43  	private static void destroy(EntityManager emgr) {
44  		if (emgr!=null && emgr.isOpen()) {
45  			if (emgr.getTransaction().isActive()) {
46  				if (emgr.getTransaction().getRollbackOnly()) {
47  					emgr.getTransaction().rollback();
48  				} else {
49  					emgr.getTransaction().commit();
50  				}
51  			}
52  			emgr.close();
53  		}
54  	}
55  	
56  
57  	@Test
58  	public void testMetaModel() {
59  		log.info("*** testMetaModel ***");
60  		
61  		CriteriaBuilder cb = em.getCriteriaBuilder();
62  		CriteriaQuery<Movie> cqdef = cb.createQuery(Movie.class);
63  		Root<Movie> m = cqdef.from(Movie.class);
64  		EntityType<Movie> m_ = m.getModel();
65  		
66  		//metamodel can be inspected
67  		for (Attribute<? super Movie, ?> prop: m_.getAttributes()) {
68  			log.info(String.format("%20s\t%s:%s", prop.getPersistentAttributeType(), prop.getName(), prop.getJavaType()));
69  		}
70  		
71  		//metamodel can be used for type-safe property access
72  		Join<Movie,String> genre = m.join(m_.getSet("genres", String.class)); 
73  		cqdef.select(m).distinct(true)
74  			.where(cb.equal(
75  					m.get(m_.getSingularAttribute("rating",MovieRating.class)), 
76  					MovieRating.R),
77  		       cb.like(genre, "Comedy"),
78  			   cb.greaterThanOrEqualTo(
79  					   m.get(m_.getSingularAttribute("releaseDate", Date.class)), 
80  					   new GregorianCalendar(1995,0,0).getTime())
81  				);
82  		TypedQuery<Movie> cquery = em2.createQuery(cqdef);
83  		
84  		log.debug("execute Criteria API query");
85  		List<Movie> cresults = cquery.getResultList();		
86  		log.debug("accessing criteria results");
87  		log.debug("critera results=" + cresults);
88  	}
89  
90  	@Test
91  	public void testCanonicalMetaModel() {
92  		log.info("*** testCanonicalMetaModel ***");
93  		
94  		CriteriaBuilder cb = em.getCriteriaBuilder();
95  		CriteriaQuery<Movie> cqdef = cb.createQuery(Movie.class);
96  		Root<Movie> m = cqdef.from(Movie.class);
97  		
98  		//canonical metamodel can be used for easy, type-safe property access
99  		Join<Movie,String> genre = m.join(Movie_.genres);
100 		cqdef.select(m).distinct(true)
101 			.where(cb.equal(
102 					m.get(Movie_.rating), MovieRating.R),
103 		       cb.like(genre, "Comedy"),
104 			   cb.greaterThanOrEqualTo(
105 					   m.get(Movie_.releaseDate), 
106 					   new GregorianCalendar(1995,0,0).getTime())
107 				);
108 		TypedQuery<Movie> cquery = em2.createQuery(cqdef);
109 		
110 		log.debug("execute Criteria API query");
111 		List<Movie> cresults = cquery.getResultList();		
112 		log.debug("accessing criteria results");
113 		log.debug("critera results=" + cresults);
114 	}
115 }