/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.openjpa.persistence.jpql.joins; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.persistence.EntityManager; | |
import javax.persistence.EntityManagerFactory; | |
import javax.persistence.criteria.CriteriaBuilder; | |
import javax.persistence.criteria.CriteriaQuery; | |
import javax.persistence.criteria.JoinType; | |
import javax.persistence.criteria.Root; | |
import org.apache.openjpa.persistence.test.SQLListenerTestCase; | |
import org.junit.Assert; | |
/** | |
* Tests JQPL and Criteria API equivalent using left join fetch with QueryCache and DataCache enabled. | |
*/ | |
public class TestJoinFetchWithQueryDataCache extends SQLListenerTestCase { | |
EntityManager em; | |
@Override | |
public void setUp() { | |
super.setUp(DROP_TABLES, Employee.class, Department.class, "openjpa.QueryCompilationCache", "all", | |
"openjpa.DataCache", "true", "openjpa.RemoteCommitProvider", "sjvm", "openjpa.QueryCache", "true" | |
// This is a hack to work around using em.detach(...) w/ a 1.0 p.xml | |
, "openjpa.Compatibility", "CopyOnDetach=false" | |
); | |
em = emf.createEntityManager(); | |
em.getTransaction().begin(); | |
Department dept; | |
dept = new Department(10, "department 10"); | |
dept.setEmployees(new ArrayList<Employee>()); | |
dept.getEmployees().add(new Employee(11, "Emp11", dept)); | |
dept.getEmployees().add(new Employee(12, "Emp12", dept)); | |
dept.setEmployee2s(new ArrayList<Employee>()); | |
dept.getEmployee2s().add(new Employee(211, "Emp211", dept)); | |
dept.getEmployee2s().add(new Employee(212, "Emp212", dept)); | |
em.persist(dept); | |
dept = new Department(20, "department 20"); | |
dept.setEmployees(new ArrayList<Employee>()); | |
dept.getEmployees().add(new Employee(21, "Emp21", dept)); | |
dept.getEmployees().add(new Employee(22, "Emp22", dept)); | |
dept.setEmployee2s(new ArrayList<Employee>()); | |
dept.getEmployee2s().add(new Employee(221, "Emp221", dept)); | |
dept.getEmployee2s().add(new Employee(222, "Emp222", dept)); | |
em.persist(dept); | |
em.getTransaction().commit(); | |
em.close(); | |
} | |
public void testJPQLNoFetch() { | |
EntityManager em = emf.createEntityManager(); | |
List<Department> ds = em.createQuery("SELECT DISTINCT d FROM Department d WHERE d.deptno = 10").getResultList(); | |
System.out.println("-- testJPQLNoFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNull(x.getEmployees()); | |
Assert.assertNull(x.getEmployee2s()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testJPQLOneFetch() { | |
EntityManager em = emf.createEntityManager(); | |
List<Department> ds = | |
em.createQuery("SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.employee2s " + "WHERE d.deptno = 10") | |
.getResultList(); | |
System.out.println("-- testJPQLOneFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNull(x.getEmployees()); | |
Assert.assertNotNull(x.getEmployee2s()); | |
Assert.assertEquals(2, x.getEmployee2s().size()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testJPQLTwoFetch() { | |
EntityManager em = emf.createEntityManager(); | |
List<Department> ds = | |
em.createQuery( | |
"SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.employees " + "LEFT JOIN FETCH d.employee2s " | |
+ "WHERE d.deptno = 10").getResultList(); | |
System.out.println("-- testJPQLTwoFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNotNull(x.getEmployees()); | |
Assert.assertEquals(2, x.getEmployees().size()); | |
Assert.assertNotNull(x.getEmployee2s()); | |
Assert.assertEquals(2, x.getEmployee2s().size()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testCriteriaAPINoFetch() { | |
EntityManager em = emf.createEntityManager(); | |
CriteriaBuilder cb = em.getCriteriaBuilder(); | |
// This query is equivalent to the following Java Persistence query | |
// language query: | |
// SELECT d | |
// FROM Department d | |
// WHERE d.deptno = 1 | |
CriteriaQuery<Department> q = cb.createQuery(Department.class); | |
Root<Department> d = q.from(Department.class); | |
q.where(cb.equal(d.get(Department_.deptno), 20)).select(d); | |
List<Department> ds = em.createQuery(q).getResultList(); | |
System.out.println("-- testCriteriaAPINoFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNull(x.getEmployees()); | |
Assert.assertNull(x.getEmployee2s()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testCriteriaAPIOneFetch() { | |
EntityManager em = emf.createEntityManager(); | |
CriteriaBuilder cb = em.getCriteriaBuilder(); | |
// 6.5.4 Fetch Joins | |
// Example: | |
// CriteriaQuery<Department> q = cb.createQuery(Department.class); | |
// Root<Department> d = q.from(Department.class); | |
// d.fetch(Department_.employees, JoinType.LEFT); | |
// q.where(cb.equal(d.get(Department_.deptno), 1)).select(d); | |
// | |
// This query is equivalent to the following Java Persistence query | |
// language query: | |
// SELECT DISTINCT d | |
// FROM Department d LEFT JOIN FETCH d.employees | |
// WHERE d.deptno = 1 | |
CriteriaQuery<Department> q = cb.createQuery(Department.class); | |
Root<Department> d = q.from(Department.class); | |
d.fetch(Department_.employees, JoinType.LEFT); | |
q.where(cb.equal(d.get(Department_.deptno), 20)).select(d).distinct(true); | |
List<Department> ds = em.createQuery(q).getResultList(); | |
System.out.println("-- testCriteriaAPIOneFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNotNull(x.getEmployees()); | |
Assert.assertEquals(2, x.getEmployees().size()); | |
Assert.assertNull(x.getEmployee2s()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testCriteriaAPITwoFetch() { | |
EntityManager em = emf.createEntityManager(); | |
CriteriaBuilder cb = em.getCriteriaBuilder(); | |
// This query is equivalent to the following Java Persistence query | |
// language query: | |
// SELECT DISTINCT d | |
// FROM Department d LEFT JOIN FETCH d.employees LEFT JOIN FETCH d.employee2s | |
// WHERE d.deptno = 1 | |
CriteriaQuery<Department> q = cb.createQuery(Department.class); | |
Root<Department> d = q.from(Department.class); | |
d.fetch(Department_.employees, JoinType.LEFT); | |
d.fetch(Department_.employee2s, JoinType.LEFT); | |
q.where(cb.equal(d.get(Department_.deptno), 20)).select(d).distinct(true); | |
List<Department> ds = em.createQuery(q).getResultList(); | |
System.out.println("-- testCriteriaAPITwoFetch -----"); | |
em.clear(); | |
Assert.assertEquals(1, ds.size()); | |
for (Department x : ds) { | |
Assert.assertNotNull(x.getEmployees()); | |
Assert.assertEquals(2, x.getEmployees().size()); | |
Assert.assertNotNull(x.getEmployee2s()); | |
Assert.assertEquals(2, x.getEmployee2s().size()); | |
System.out.println(x); | |
} | |
em.close(); | |
} | |
public void testConsecutiveJPQLJoinFetchCall() { | |
doQuery(emf, false); | |
doQuery(emf, true); | |
} | |
private void doQuery(EntityManagerFactory emf, boolean cached) { | |
String query = "select o from Employee o " + "left join fetch o.dept " + "where o.dept.deptno = 10"; | |
EntityManager em = emf.createEntityManager(); | |
sql.clear(); | |
List<Employee> emps = em.createQuery(query, Employee.class).getResultList(); | |
Assert.assertEquals(4, emps.size()); | |
for (Employee emp : emps) { | |
em.detach(emp); | |
Assert.assertNotNull(emp.getDept()); | |
Assert.assertEquals(2, emp.getDept().getEmployees().size()); | |
} | |
em.close(); | |
if (cached) { | |
assertTrue(sql.size() == 0); | |
} | |
} | |
} |