blob: a2cf0155124e21a5fad3d6f388f3890f4b57b0fe [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.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
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 SimpleDefaultFetchGroupTests extends BaseFetchGroupTests {
public SimpleDefaultFetchGroupTests() {
super();
}
public SimpleDefaultFetchGroupTests(String name) {
super(name);
}
public static junit.framework.Test suite() {
TestSuite suite = new TestSuite();
suite.setName("SimpleDefaultFetchGroupTests");
suite.addTest(new SimpleDefaultFetchGroupTests("testSetup"));
suite.addTest(new SimpleDefaultFetchGroupTests("findDefaultFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("singleResultDefaultFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("resultListDefaultFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("resultListWithJoinFetchAddress"));
suite.addTest(new SimpleDefaultFetchGroupTests("resultListWithJoinFetchAddress_AddressInFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("singleResultNoFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("resultListNoFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("emptyFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("managerFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("employeeNamesFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("namedEmptyFetchGroupUsingGetSingleResult"));
suite.addTest(new SimpleDefaultFetchGroupTests("namedNamesFetchGroupUsingGetSingleResult"));
suite.addTest(new SimpleDefaultFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup_AddressInFetchGroup"));
suite.addTest(new SimpleDefaultFetchGroupTests("readThroughServerSession"));
return suite;
}
/**
* Set default fetch groups.
*
* @see EmployeeCustomizer
* @see PhoneCustomizer
*/
@Override
public void setUp() {
super.setUp();
try {
(new EmployeeCustomizer()).customize(employeeDescriptor);
(new PhoneCustomizer()).customize(phoneDescriptor);
// reprepare read queries after all fetch groups set into all descriptors.
reprepareReadQueries(employeeDescriptor);
reprepareReadQueries(phoneDescriptor);
} catch (RuntimeException rtEx) {
throw rtEx;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
FetchGroup defaultEmpFG = employeeDescriptor.getDefaultFetchGroup();
FetchGroup defaultPhoneFG = phoneDescriptor.getDefaultFetchGroup();
assertConfig(employeeDescriptor, defaultEmpFG, 0);
assertConfig(phoneDescriptor, defaultPhoneFG, 0);
}
@Test
public void findDefaultFetchGroup() throws Exception {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Employee emp = minimumEmployee(em);
assertNotNull(emp);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertDefaultFetched(emp);
assertNotFetchedAttribute(emp, "salary");
emp.getSalary();
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetchedAttribute(emp, "salary");
assertNoFetchGroup(emp.getAddress());
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
int nSqlExpected = 4;
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
nSqlExpected--;
}
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getManager() != null) {
assertDefaultFetched(emp.getManager());
assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void singleResultDefaultFetchGroup() 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));
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertDefaultFetched(emp);
emp.getSalary();
assertFetchedAttribute(emp, "salary");
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
int nSqlExpected = 5;
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
nSqlExpected--;
}
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getManager() != null) {
assertDefaultFetched(emp.getManager());
assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void resultListDefaultFetchGroup() 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));
List<Employee> emps = query.getResultList();
assertNotNull(emps);
assertEquals(1, emps.size());
Employee emp = emps.get(0);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertDefaultFetched(emp);
emp.getSalary();
assertNoFetchGroup(emp);
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
int nSqlExpected = 5;
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
nSqlExpected--;
}
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getManager() != null) {
assertDefaultFetched(emp.getManager());
assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void resultListWithJoinFetchAddress() {
internalResultListWithJoinFetchAddress(false);
}
@Test
public void resultListWithJoinFetchAddress_AddressInFetchGroup() {
internalResultListWithJoinFetchAddress(true);
}
void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
FetchGroup fg = null;
if(addAddressToFetchGroup) {
// that returns clone of the default fetch group
fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup();
fg.addAttribute("address");
query.setHint(QueryHints.FETCH_GROUP, fg);
}
Employee emp = (Employee)query.getSingleResult();
int nSql = 2;
if(!addAddressToFetchGroup) {
// An extra sql to read employee's Address -
// because address attribute is not in the fetch group the Address object was not built
// by join fetch - though the db row for address was read in.
//
// yet another extra sql generated when the whole employee object is read when address is set.
nSql = nSql + 2;
}
assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if(addAddressToFetchGroup) {
assertFetched(emp, fg);
} else {
// the whole object has been instantiated when address has been set
assertNoFetchGroup(emp);
}
// instantiates the whole object - unless already instantiated
emp.getSalary();
assertNoFetchGroup(emp);
if(addAddressToFetchGroup) {
nSql++;
}
assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp.getAddress());
assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
} else {
++nSql;
}
assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if (emp.getManager() != null) {
assertDefaultFetched(emp.getManager());
assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void singleResultNoFetchGroup() 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));
assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup());
query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
assertNull(getFetchGroup(query));
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
assertNoFetchGroup(emp.getAddress());
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void resultListNoFetchGroup() 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));
query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
List<Employee> emps = query.getResultList();
assertNotNull(emps);
assertEquals(1, emps.size());
Employee emp = emps.get(0);
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
assertNoFetchGroup(emp.getAddress());
assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
}
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void emptyFetchGroup() 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));
FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis());
query.setHint(QueryHints.FETCH_GROUP, emptyFG);
assertEquals(emptyFG, getFetchGroup(query));
Employee emp = (Employee) query.getSingleResult();
assertFetched(emp, emptyFG);
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
phone.getAreaCode();
assertNoFetchGroup(phone);
}
} 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);
query.setHint(QueryHints.LEFT_FETCH, "e.manager");
assertEquals(managerFG, getFetchGroup(query));
List employees = query.getResultList();
Employee emp = (Employee)employees.get(0);
assertFetched(emp, managerFG);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
emp.getManager();
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, managerFG);
emp.getLastName();
assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertNoFetchGroup(emp);
int numPhones = 0;
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
phone.getAreaCode();
assertNoFetchGroup(phone);
numPhones++;
}
// 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
int nSqlExpected = 3 + numPhones;
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
nSqlExpected--;
}
assertEquals(nSqlExpected, 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);
int numPhones = 0;
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertDefaultFetched(phone);
phone.getAreaCode();
assertNoFetchGroup(phone);
numPhones++;
}
// 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
int nSqlExpected = 4 + numPhones;
if (usesSOP()) {
// When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
nSqlExpected--;
}
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
if(emp.getManager() != null) {
assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertDefaultFetched(emp.getManager());
} else {
// If manager_id field is null then getManager() does not trigger an sql.
assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void namedEmptyFetchGroupUsingGetSingleResult() throws Exception {
FetchGroup fetchGroup = new FetchGroup("test");
employeeDescriptor.getFetchGroupManager().addFetchGroup(fetchGroup);
assertTrue(fetchGroup.getItems().isEmpty());
assertEquals(1, employeeDescriptor.getFetchGroupManager().getFetchGroups().size());
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
query.setHint(QueryHints.FETCH_GROUP_NAME, "test");
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
assertFetched(emp, "test");
}
@Test
public void namedNamesFetchGroupUsingGetSingleResult() throws Exception {
FetchGroup fetchGroup = new FetchGroup("names");
fetchGroup.addAttribute("firstName");
fetchGroup.addAttribute("lastName");
employeeDescriptor.getFetchGroupManager().addFetchGroup(fetchGroup);
assertEquals(2, fetchGroup.getItems().size());
assertEquals(1, employeeDescriptor.getFetchGroupManager().getFetchGroups().size());
EntityManager em = createEntityManager();
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", minimumEmployeeId(em));
query.setHint(QueryHints.FETCH_GROUP_NAME, "names");
Employee emp = (Employee) query.getSingleResult();
assertNotNull(emp);
FetchGroupTracker tracker = (FetchGroupTracker) emp;
assertNotNull(tracker);
FetchGroup usedFG = tracker._persistence_getFetchGroup();
assertNotNull("No FetchGroup found on read Employee", fetchGroup);
// No longer can make any assumptions about a name of FetchGroup on the entity
// What's guaranteed is that attribute sets are the same
assertTrue(fetchGroup.getAttributeNames().equals(usedFG.getAttributeNames()));
// assertEquals(fetchGroup.getName(), usedFG.getName());
// assertSame(fetchGroup, ((EntityFetchGroup)usedFG).getParent());
assertEquals(4, fetchGroup.getItems().size());
assertTrue(tracker._persistence_isAttributeFetched("id"));
assertTrue(tracker._persistence_isAttributeFetched("version"));
assertFalse(tracker._persistence_isAttributeFetched("salary"));
assertTrue(tracker._persistence_isAttributeFetched("firstName"));
assertTrue(tracker._persistence_isAttributeFetched("lastName"));
assertFalse(tracker._persistence_isAttributeFetched("department"));
}
@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() {
internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(false);
}
@Test
public void joinFetchEmployeeAddressPhoneWithDynamicFetchGroup_AddressInFetchGroup() {
internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(true);
}
void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
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");
if(addAddressToFetchGroup) {
fetchGroup.addAttribute("address");
}
query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
List<Employee> emps = query.getResultList();
assertNotNull(emps);
if(addAddressToFetchGroup) {
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
} else {
assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
}
for (Employee emp : emps) {
if(addAddressToFetchGroup) {
assertFetched(emp, fetchGroup);
} else {
// the whole object has been instantiated when address has been set
assertNoFetchGroup(emp);
}
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
@Test
public void readThroughServerSession() {
List<Employee> emps = null;
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL");
emps = query.getResultList();
assertNotNull(emps);
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
EntityManager em2 = createEntityManager();
try {
beginTransaction(em2);
em2.flush();
Query query = em2.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL");
emps = query.getResultList();
Employee emp = emps.get(0);
emp.getAddress().setCountry("newCountry");
commitTransaction(em2);
} finally {
if (isTransactionActive(em2)){
rollbackTransaction(em2);
}
closeEntityManager(em2);
}
}
public static class EmployeeCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor descriptor) throws Exception {
FetchGroup fg = new FetchGroup("Employee-default");
fg.addAttribute("firstName");
fg.addAttribute("lastName");
descriptor.getFetchGroupManager().setDefaultFetchGroup(fg);
}
}
/* public static class PhoneCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) throws Exception {
FetchGroup fg = new FetchGroup("Phone-default");
fg.addAttribute("number");
if (!descriptor.hasFetchGroupManager()) {
descriptor.setFetchGroupManager(new FetchGroupManager());
}
descriptor.getFetchGroupManager().setDefaultFetchGroup(fg);
}
}*/
}