blob: 6683f5a4fb65a8750c29a33ba99b734517deb89f [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// 05/19/2010-2.1 ailitchev - Bug 244124 - Add Nested FetchGroup
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.junit.Test;
/**
* Simple tests to verify the functionality of single level FetchGroup usage
*
* @author dclarke
* @since EclipseLink 2.1
*/
public class SimpleFetchGroupTests extends BaseFetchGroupTests {
public SimpleFetchGroupTests() {
super();
}
public SimpleFetchGroupTests(String name) {
super(name);
}
public static junit.framework.Test suite() {
TestSuite suite = new TestSuite();
suite.setName("SimpleFetchGroupTests");
suite.addTest(new SimpleFetchGroupTests("testSetup"));
suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("managerFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("managerFetchGroupWithJoinFetch"));
suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes"));
suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup"));
if (!isJPA10()) {
suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup"));
suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes"));
suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup"));
}
return suite;
}
@Test
public void findNoFetchGroup() throws Exception {
EntityManager em = createEntityManager();
int minId = minimumEmployeeId(em);
Employee emp = em.find(Employee.class, minId);
assertNotNull(emp);
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertFetchedAttribute(emp, "firstName");
assertFetchedAttribute(emp, "lastName");
assertFetchedAttribute(emp, "gender");
assertFetchedAttribute(emp, "salary");
assertFetchedAttribute(emp, "startTime");
assertFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
@Test
public void singleResultNoFetchGroup() throws Exception {
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertFetchedAttribute(emp, "firstName");
assertFetchedAttribute(emp, "lastName");
assertFetchedAttribute(emp, "gender");
assertFetchedAttribute(emp, "salary");
assertFetchedAttribute(emp, "startTime");
assertFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
public void resultListNoFetchGroup() throws Exception {
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
List<Employee> emps = query.getResultList();
assertNotNull(emps);
assertEquals(1, emps.size());
Employee emp = emps.get(0);
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertFetchedAttribute(emp, "firstName");
assertFetchedAttribute(emp, "lastName");
assertFetchedAttribute(emp, "gender");
assertFetchedAttribute(emp, "salary");
assertFetchedAttribute(emp, "startTime");
assertFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
}
@Test
public void findEmptyFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
int minId = minimumEmployeeId(em);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
Map<String, Object> properties = new HashMap<String, Object>();
FetchGroup emptyFG = new FetchGroup();
properties.put(QueryHints.FETCH_GROUP, emptyFG);
Employee emp = em.find(Employee.class, minId, properties);
assertNotNull(emp);
assertFetched(emp, emptyFG);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertNotFetchedAttribute(emp, "firstName");
assertNotFetchedAttribute(emp, "lastName");
assertNotFetchedAttribute(emp, "gender");
assertNotFetchedAttribute(emp, "salary");
assertNotFetchedAttribute(emp, "startTime");
assertNotFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
emp.getSalary();
assertFetchedAttribute(emp, "salary");
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
emp.getAddress();
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
emp.getPhoneNumbers().size();
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
}
if (emp.getManager() != null) {
assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
}finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
int minId = minimumEmployeeId(em);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
Map<String, Object> properties = new HashMap<String, Object>();
FetchGroup emptyFG = new FetchGroup();
properties.put(QueryHints.FETCH_GROUP, emptyFG);
Employee emp = em.find(Employee.class, minId, properties);
assertNotNull(emp);
assertFetched(emp, emptyFG);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertNotFetchedAttribute(emp, "firstName");
assertNotFetchedAttribute(emp, "lastName");
assertNotFetchedAttribute(emp, "gender");
assertNotFetchedAttribute(emp, "salary");
assertNotFetchedAttribute(emp, "startTime");
assertNotFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
emp.setSalary(1);
assertFetchedAttribute(emp, "salary");
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
emp.getAddress();
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
emp.getPhoneNumbers().size();
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void singleResultEmptyFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
FetchGroup emptyFG = new FetchGroup();
query.setHint(QueryHints.FETCH_GROUP, emptyFG);
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
assertFetched(emp, emptyFG);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertNotFetchedAttribute(emp, "firstName");
assertNotFetchedAttribute(emp, "lastName");
assertNotFetchedAttribute(emp, "gender");
assertNotFetchedAttribute(emp, "salary");
assertNotFetchedAttribute(emp, "startTime");
assertNotFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
emp.getSalary();
assertFetchedAttribute(emp, "salary");
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
emp.getAddress();
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
emp.getPhoneNumbers().size();
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
/**
*
*/
@Test
public void resultListEmptyFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
FetchGroup emptyFG = new FetchGroup();
query.setHint(QueryHints.FETCH_GROUP, emptyFG);
List<Employee> emps = query.getResultList();
assertNotNull(emps);
assertEquals(1, emps.size());
Employee emp = emps.get(0);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, emptyFG);
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertNotFetchedAttribute(emp, "firstName");
assertNotFetchedAttribute(emp, "lastName");
assertNotFetchedAttribute(emp, "gender");
assertNotFetchedAttribute(emp, "salary");
assertNotFetchedAttribute(emp, "startTime");
assertNotFetchedAttribute(emp, "endTime");
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
emp.getSalary();
assertFetchedAttribute(emp, "salary");
assertNoFetchGroup(emp);
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
}
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
/**
*
*/
@Test
public void resultListPeriodFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
FetchGroup fg = new FetchGroup();
fg.addAttribute("period");
query.setHint(QueryHints.FETCH_GROUP, fg);
List<Employee> emps = query.getResultList();
assertNotNull(emps);
assertEquals(1, emps.size());
Employee emp = emps.get(0);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, fg);
// Check Basics
assertFetchedAttribute(emp, "id");
assertFetchedAttribute(emp, "version");
assertNotFetchedAttribute(emp, "firstName");
assertNotFetchedAttribute(emp, "lastName");
assertNotFetchedAttribute(emp, "gender");
assertNotFetchedAttribute(emp, "salary");
assertNotFetchedAttribute(emp, "startTime");
assertNotFetchedAttribute(emp, "endTime");
if (emp.getPeriod() != null) {
assertFetchedAttribute(emp.getPeriod(), "startDate");
assertFetchedAttribute(emp.getPeriod(), "endDate");
}
// Check Relationships
assertNotFetchedAttribute(emp, "address");
assertNotFetchedAttribute(emp, "manager");
assertNotFetchedAttribute(emp, "phoneNumbers");
assertNotFetchedAttribute(emp, "projects");
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
emp.getSalary();
assertFetchedAttribute(emp, "salary");
assertNoFetchGroup(emp);
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
}
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Override
@Test
public void managerFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
// Use q query since find will only use default fetch group
//Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
//query.setParameter("ID", minimumEmployeeId(em));
// Complex where clause used to avoid triggering employees and their departments:
// Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
// Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL");
FetchGroup managerFG = new FetchGroup();
managerFG.addAttribute("manager");
query.setHint(QueryHints.FETCH_GROUP, managerFG);
assertNotNull(getFetchGroup(query));
assertSame(managerFG, getFetchGroup(query));
Employee emp = (Employee) query.getSingleResult();
assertFetched(emp, managerFG);
//int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
// manager hasn't been instantiated yet
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
int nSqlToAdd = 0;
if (emp.getManager() != null) {
assertFetchedAttribute(emp, "manager");
// additional sql to select the manager
nSqlToAdd++;
}
assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// acuses instantioation of the whole object
emp.getLastName();
assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
phone.getAreaCode();
}
assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void managerFetchGroupWithJoinFetch() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
//int minId = minimumEmployeeId(em);
//assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Use q query since find will only use default fetch group
//Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
//query.setParameter("ID", minId);
// Complex where clause used to avoid triggering employees and their departments:
// Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
// Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL");
FetchGroup managerFG = new FetchGroup();
managerFG.addAttribute("manager");
query.setHint(QueryHints.FETCH_GROUP, managerFG);
query.setHint(QueryHints.LEFT_FETCH, "e.manager");
assertNotNull(getFetchGroup(query));
assertSame(managerFG, getFetchGroup(query));
Employee emp = (Employee) query.getSingleResult();
assertFetched(emp, managerFG);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// manager (if not null) is instantiated by the fetch group, before emp.getManager call.
emp.getManager();
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// instantiates the whole object
emp.getLastName();
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
phone.getAreaCode();
}
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Override
@Test
public void employeeNamesFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
int minId = minimumEmployeeId(em);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// Use q query since find will only use default fetch group
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minId);
FetchGroup namesFG = new FetchGroup();
namesFG.addAttribute("firstName");
namesFG.addAttribute("lastName");
query.setHint(QueryHints.FETCH_GROUP, namesFG);
assertNotNull(getFetchGroup(query));
assertSame(namesFG, getFetchGroup(query));
Employee emp = (Employee) query.getSingleResult();
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, namesFG);
emp.getId();
emp.getFirstName();
emp.getLastName();
emp.getVersion();
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, namesFG);
emp.getGender();
emp.getSalary();
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertNoFetchGroup(phone);
phone.getAreaCode();
}
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getManager() != null) {
assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getManager());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Override
@Test
public void joinFetchEmployeeAddressWithDynamicFetchGroup() {
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address");
FetchGroup fetchGroup = new FetchGroup("names");
fetchGroup.addAttribute("firstName");
fetchGroup.addAttribute("lastName");
query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
List<Employee> emps = query.getResultList();
assertNotNull(emps);
}
@Override
@Test
public void joinFetchEmployeeAddressPhoneWithDynamicFetchGroup() {
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)");
FetchGroup fetchGroup = new FetchGroup("names");
fetchGroup.addAttribute("firstName");
fetchGroup.addAttribute("lastName");
query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
List<Employee> emps = query.getResultList();
assertNotNull(emps);
}
@Test
public void verifyUnfetchedAttributes() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
FetchGroup fg = new FetchGroup("Employee.empty");
q.setHint(QueryHints.FETCH_GROUP, fg);
Employee emp = q.getSingleResult();
assertNotNull(emp);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
// This check using the mapping returns a default (empty) IndirectList
/*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
assertNotNull(phones);
assertTrue(phones.isInstantiated());
assertEquals(0, phones.size());
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
assertFalse(phonesIL.isInstantiated());
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertTrue(emp.getPhoneNumbers().size() > 0);
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void verifyFetchedRelationshipAttributes() throws Exception {
EntityManager em = createEntityManager();
FetchGroup fg = new FetchGroup("Employee.relationships");
fg.addAttribute("address");
fg.addAttribute("phoneNumbers");
fg.addAttribute("manager");
fg.addAttribute("projects");
Map<String, Object> hints = new HashMap<String, Object>();
hints.put(QueryHints.FETCH_GROUP, fg);
Employee emp = minimumEmployee(em, hints);
assertNotNull(emp);
}
@Test
public void detachedByClosingEntityManagerObjectWithFetchGroup() {
EntityManager em = createEntityManager();
FetchGroup fg = new FetchGroup();
fg.addAttribute("firstName");
fg.addAttribute("lastName");
Map<String, Object> hints = new HashMap<String, Object>();
hints.put(QueryHints.FETCH_GROUP, fg);
Employee emp = minimumEmployee(em, hints);
assertFetched(emp, fg);
closeEntityManager(em);
// trigger the fetch group
emp.getSalary();
assertNoFetchGroup(emp);
}
@Test
public void explicitlyDetachedObjectWithFetchGroup() {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
FetchGroup fg = new FetchGroup();
fg.addAttribute("firstName");
fg.addAttribute("lastName");
Map<String, Object> hints = new HashMap<String, Object>();
hints.put(QueryHints.FETCH_GROUP, fg);
Employee emp = minimumEmployee(em, hints);
em.detach(emp);
assertFetched(emp, fg);
// trigger the fetch group
emp.getSalary();
assertNoFetchGroup(emp);
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
}