/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.queries.optimization;

import java.util.List;

import org.eclipse.persistence.tools.schemaframework.PopulationManager;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.annotations.BatchFetchType;
import org.eclipse.persistence.expressions.*;

import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.models.inheritance.Engineer;
import org.eclipse.persistence.testing.models.ownership.ObjectA;

/**
 * Test query optimization features, joining, batch reading, partial object reading.
 */
@SuppressWarnings("deprecation")
public class QueryOptimizationTestSuite extends TestSuite {
    public QueryOptimizationTestSuite() {
        setDescription("This suite tests query optimization, aggregation and batch reading.");
    }

    public void addBatchTests() {
        addBatchTests(BatchFetchType.JOIN);
        addBatchTests(BatchFetchType.EXISTS);
        addBatchTests(BatchFetchType.IN);
    }

    public void addBatchTests(BatchFetchType batchType) {
        // Batch reading
        ReadAllBatchReadingTest testbb1 = new ReadAllBatchReadingTest(12);
        testbb1.setName("ReadAllBatchReadingTestAddressManager" + batchType);
        ReadAllQuery querybb1 = new ReadAllQuery();
        querybb1.setBatchFetchType(batchType);
        querybb1.setReferenceClass(Employee.class);
        querybb1.addBatchReadAttribute("address");
        querybb1.addBatchReadAttribute("manager");
        querybb1.addBatchReadAttribute("phoneNumbers");
        querybb1.addBatchReadAttribute("projects");
        querybb1.addBatchReadAttribute("responsibilitiesList");
        testbb1.setQuery(querybb1);
        addTest(testbb1);

        ReadAllBatchReadingTest testbb2 = new ReadAllBatchReadingTest(2);
        testbb2.setName("ReadAllBatchReadingTestWhereAddressManager" + batchType);
        ReadAllQuery querybb2 = new ReadAllQuery();
        querybb2.setBatchFetchType(batchType);
        querybb2.setReferenceClass(Employee.class);
        querybb2.addBatchReadAttribute("address");
        querybb2.addBatchReadAttribute("manager");
        querybb2.addBatchReadAttribute("phoneNumbers");
        querybb2.addBatchReadAttribute("projects");
        querybb2.addBatchReadAttribute("responsibilitiesList");
        querybb2.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("lastName").equal("Way"));
        testbb2.setQuery(querybb2);
        addTest(testbb2);

        //add the BatchReadingUnitOfWorkTest and BatchReadingUnitOfWorkInTransactionTest
        BatchReadingUnitOfWorkTest testbb3 = new BatchReadingUnitOfWorkTest(batchType);
        addTest(testbb3);

        BatchReadingUnitOfWorkInTransactionTest testbb4 = new BatchReadingUnitOfWorkInTransactionTest(batchType);
        addTest(testbb4);

        //adding the OneToMany tests
        OneToManyBatchReadingTest testbb5 = new OneToManyBatchReadingTest(batchType);
        addTest(testbb5);

        addTest(new BatchReadingTest(batchType));

        OneToManyBatchReadingCustomSelectionQueryTest testbb6 = new OneToManyBatchReadingCustomSelectionQueryTest(batchType);
        addTest(testbb6);

        ReadAllBatchReadingTest test3 = new ReadAllBatchReadingTest(2);
        test3.setName("ReadAllBatchReadingTestWhereAddressManager-cursor" + batchType);
        ReadAllQuery query3 = new ReadAllQuery();
        query3.setBatchFetchType(batchType);
        query3.setReferenceClass(Employee.class);
        query3.useCursoredStream();
        query3.addBatchReadAttribute("address");
        query3.addBatchReadAttribute("manager");
        query3.addBatchReadAttribute("phoneNumbers");
        query3.addBatchReadAttribute("projects");
        querybb1.addBatchReadAttribute("responsibilitiesList");
        query3.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("lastName").equal("Way"));
        test3.setQuery(query3);
        addTest(test3);

        NestedOneToManyBatchReadAllTest test3_5 = new NestedOneToManyBatchReadAllTest(org.eclipse.persistence.testing.models.collections.Restaurant.class, 15);
        test3_5.setName("NestedOneToManyBatchReadAllTest" + batchType);
        ReadAllQuery query3_5 = new ReadAllQuery();
        query3_5.setBatchFetchType(batchType);
        query3_5.setReferenceClass(org.eclipse.persistence.testing.models.collections.Restaurant.class);
        query3_5.addBatchReadAttribute("menus");
        test3_5.setQuery(query3_5);
        addTest(test3_5);

        //Batch testing on 1-1 mapping
        ReadAllTest test4 = new ReadAllTest(org.eclipse.persistence.testing.models.insurance.Policy.class, 3);
        test4.setName("ReadAllBatchReadingTestPolicyHolder" + batchType);
        ReadAllQuery query4 = new ReadAllQuery();
        query4.setBatchFetchType(batchType);
        query4.setReferenceClass(org.eclipse.persistence.testing.models.insurance.Policy.class);
        query4.addBatchReadAttribute("policyHolder");
        query4.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("maxCoverage").greaterThan(40000));
        test4.setQuery(query4);
        addTest(test4);

        addTest(new OneToOneBatchReadingTest(batchType));

        // Batch testing on 1-M mapping.
        ReadAllTest test5 = new ReadAllTest(org.eclipse.persistence.testing.models.insurance.Policy.class, 4);
        test5.setName("ReadAllBatchReadingTestClaim" + batchType);
        ReadAllQuery query5 = new ReadAllQuery();
        query5.setBatchFetchType(batchType);
        query5.setReferenceClass(org.eclipse.persistence.testing.models.insurance.Policy.class);
        query5.addBatchReadAttribute("claims");
        query5.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("maxCoverage").greaterThan(30000));
        test5.setQuery(query5);
        addTest(test5);

        addTest(new OneToManyBatchReadingTest(batchType));

        addTest(new NestedBatchReadingTest(batchType));
        addTest(new NestedBatchReadingNPETest(batchType));
        addTest(new AggregateBatchReadingTest(batchType));
        addTest(new BatchReadingBatchReadExpressionTest(batchType));
        addTest(new BatchReadingWithInvalidQueryKeyTest(batchType));
        addTest(new BatchReadValueholderTest(batchType));

        addTest(new BatchReadingStackOverflowTest(batchType));
    }

    public void addJoinTests() {
        PopulationManager manager = PopulationManager.getDefaultManager();
        Employee object = (Employee)manager.getObject(Employee.class, "0002");

        // Joining
        ReadObjectTest test = new ReadObjectTest(object);
        test.setName("JoiningReadObjectTestAddress");
        ReadObjectQuery query = new ReadObjectQuery();
        query.setSelectionObject(object);
        query.addJoinedAttribute("address");
        test.setQuery(query);
        addTest(test);

        ReadObjectTest test1a = new ReadObjectTest(object);
        test1a.setName("JoiningReadObjectTestAddressManager");
        ReadObjectQuery query1a = new ReadObjectQuery();
        query1a.setSelectionObject(object);
        query1a.addJoinedAttribute("address");
        query1a.addJoinedAttribute("manager");
        test1a.setQuery(query1a);
        addTest(test1a);

        ReadObjectTest test1m = new ReadObjectTest(object);
        test1m.setName("JoiningReadObjectTestPhones");
        ReadObjectQuery query1m = new ReadObjectQuery();
        query1m.setSelectionObject(object);
        query1m.addJoinedAttribute(query1m.getExpressionBuilder().anyOf("phoneNumbers"));
        test1m.setQuery(query1m);
        addTest(test1m);

        test1m = new ReadObjectTest(object);
        test1m.setName("JoiningReadObjectTestPhonesOuter");
        query1m = new ReadObjectQuery();
        query1m.setSelectionObject(object);
        query1m.addJoinedAttribute(query1m.getExpressionBuilder().anyOfAllowingNone("phoneNumbers"));
        test1m.setQuery(query1m);
        addTest(test1m);

        addTest(new ReadAnyObjectJoinPhoneTest());

        Object person = manager.getObject(Engineer.class, "example2");
        ReadObjectTest test1b = new ReadObjectTest(person);
        test1b.setName("JoiningInheritanceRelationshipTest");
        ReadObjectQuery query1b = new ReadObjectQuery();
        query1b.setSelectionObject(person);
        query1b.addJoinedAttribute("bestFriend");
        query1b.addJoinedAttribute("representitive");
        test1b.setQuery(query1b);
        addTest(test1b);

        ReadObjectTest test1bx = new ReadObjectTest(person);
        test1bx.setName("NestedJoiningInheritanceRelationshipTest");
        ReadObjectQuery query1bx = new ReadObjectQuery();
        query1bx.setSelectionObject(person);
        query1bx.addJoinedAttribute(query1bx.getExpressionBuilder().get("bestFriend"));
        query1bx.addJoinedAttribute(query1bx.getExpressionBuilder().get("bestFriend").getAllowingNull("bestFriend"));
        query1bx.addJoinedAttribute(query1bx.getExpressionBuilder().get("bestFriend").getAllowingNull("representitive"));
        query1bx.addJoinedAttribute(query1bx.getExpressionBuilder().get("representitive"));
        test1bx.setQuery(query1bx);
        addTest(test1bx);

        ReadObjectTest test1c = new ReadObjectTest(object);
        test1c.setName("JoiningReadObjectTestAddressManagerManager");
        ReadObjectQuery query1c = new ReadObjectQuery();
        query1c.setSelectionObject(object);
        query1c.addJoinedAttribute("address");
        query1c.addJoinedAttribute("manager");
        query1c.addJoinedAttribute(query1c.getExpressionBuilder().get("manager").get("manager"));
        test1c.setQuery(query1c);
        addTest(test1c);

        ReadAllTest test2 = new ReadAllTest(Employee.class, 12);
        test2.setName("JoiningReadAllTestAddress");
        ReadAllQuery query2 = new ReadAllQuery();
        query2.setReferenceClass(Employee.class);
        query2.addJoinedAttribute("address");
        query2.addJoinedAttribute(query2.getExpressionBuilder().getAllowingNull("manager"));
        test2.setQuery(query2);
        addTest(test2);

        ReadAllTest testReadAll1m = new ReadAllTest(Employee.class, 12);
        testReadAll1m.setName("JoiningReadAllTestPhones");
        ReadAllQuery queryReadAll1m = new ReadAllQuery();
        queryReadAll1m.setReferenceClass(Employee.class);
        queryReadAll1m.addJoinedAttribute(queryReadAll1m.getExpressionBuilder().anyOf("phoneNumbers"));
        testReadAll1m.setQuery(queryReadAll1m);
        addTest(testReadAll1m);

        ReadAllTest testReadAll21m = new ReadAllTest(Employee.class, 5);
        testReadAll21m.setName("JoiningReadAllTestPhonesManagedEmployeesPhones");
        ReadAllQuery queryReadAll21m = new ReadAllQuery();
        queryReadAll21m.setReferenceClass(Employee.class);
        Expression managedEmployee = queryReadAll21m.getExpressionBuilder().anyOf("managedEmployees");
        queryReadAll21m.addJoinedAttribute(queryReadAll21m.getExpressionBuilder().anyOf("phoneNumbers"));
        queryReadAll21m.addJoinedAttribute(managedEmployee);
        queryReadAll21m.addJoinedAttribute(managedEmployee.anyOf("phoneNumbers"));
        testReadAll21m.setQuery(queryReadAll21m);
        addTest(testReadAll21m);

        ReadAllTest test2a = new ReadAllTest(Employee.class, 2);
        test2a.setName("JoiningReadAllTestWhereLastNameWay");
        ReadAllQuery query2a = new ReadAllQuery();
        query2a.setReferenceClass(Employee.class);
        query2a.addJoinedAttribute("address");
        query2a.setSelectionCriteria(new ExpressionBuilder().get("lastName").equal("Way"));
        test2a.setQuery(query2a);
        addTest(test2a);

        ReadObjectTest test2az = new ReadObjectTest(object);
        test2az.setName("JoiningReadObjectTestCustomSQL");
        ReadObjectQuery query2az = new ReadObjectQuery();
        query2az.setReferenceClass(Employee.class);
        query2az.addJoinedAttribute("address");
        query2az.setSQLString("Select * from EMPLOYEE E, SALARY S, ADDRESS A WHERE E.EMP_ID = S.EMP_ID AND E.ADDR_ID = A.ADDRESS_ID AND E.EMP_ID = " + object.getId());
        test2az.setQuery(query2az);
        addTest(test2az);

        ReadAllTest test2ax = new ReadAllTest(Employee.class, 2);
        test2ax.setName("JoiningReadAllTestCustomSQL");
        ReadAllQuery query2ax = new ReadAllQuery();
        query2ax.setReferenceClass(Employee.class);
        query2ax.addJoinedAttribute("address");
        query2ax.setSQLString("Select * from EMPLOYEE E, SALARY S, ADDRESS A WHERE E.EMP_ID = S.EMP_ID AND E.ADDR_ID = A.ADDRESS_ID AND E.L_NAME = 'Way'");
        test2ax.setQuery(query2ax);
        addTest(test2ax);

        ReadAllTest test2aa = new ReadAllTest(Employee.class, 2);
        test2aa.setName("JoiningReadAllTestWhereLastNameWay-cursor");
        ReadAllQuery query2aa = new ReadAllQuery();
        query2aa.setReferenceClass(Employee.class);
        query2aa.useCursoredStream();
        query2aa.addJoinedAttribute("address");
        query2aa.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("lastName").equal("Way"));
        test2aa.setQuery(query2aa);
        addTest(test2aa);

        ReadAllJoinReadingTest test2b = new ReadAllJoinReadingTest(3, "teamLeader-address");
        ReadAllQuery query2b = new ReadAllQuery();
        query2b.setReferenceClass(LargeProject.class);
        query2b.addJoinedAttribute(query2b.getExpressionBuilder().get("teamLeader"));
        query2b.addJoinedAttribute(query2b.getExpressionBuilder().get("teamLeader").get("address"));
        test2b.setQuery(query2b);
        addTest(test2b);

        ReadAllTest ownerTest = new ReadAllTest(ObjectA.class, 3);
        ownerTest.setName("JoinOwnerA-oneToOne-oneToMany");
        ReadAllQuery ownerQuery = new ReadAllQuery();
        ownerQuery.setReferenceClass(ObjectA.class);
        ownerQuery.addJoinedAttribute(ownerQuery.getExpressionBuilder().get("oneToOne"));
        ownerQuery.addJoinedAttribute(ownerQuery.getExpressionBuilder().get("oneToOne").anyOf("oneToMany"));
        ownerTest.setQuery(ownerQuery);
        addTest(ownerTest);

        ReadAllTest ownerTest3 = new ReadAllTest(ObjectA.class, 3);
        ownerTest3.setName("JoinOwnerA-oneToOne-oneToMany-oneToOne");
        ReadAllQuery ownerQuery3 = new ReadAllQuery();
        ownerQuery3.setReferenceClass(ObjectA.class);
        ownerQuery3.addJoinedAttribute(ownerQuery.getExpressionBuilder().get("oneToOne"));
        Expression join = ownerQuery.getExpressionBuilder().get("oneToOne").anyOf("oneToMany");
        ownerQuery3.addJoinedAttribute(join);
        ownerQuery3.addJoinedAttribute(join.get("oneToOne"));
        ownerTest3.setQuery(ownerQuery3);
        addTest(ownerTest3);

        ReadAllTest ownerTest2 = new ReadAllTest(ObjectA.class, 3);
        ownerTest2.setName("JoinOwnerA-oneToOne(mapping)");
        ReadAllQuery ownerQuery2 = new ReadAllQuery();
        ownerQuery2.setReferenceClass(ObjectA.class);
        ownerTest2.setQuery(ownerQuery2);
        addTest(ownerTest2);

        ReadAllTest test3 = new ReadAllTest(LargeProject.class, 3);
        ReadAllQuery query3 = new ReadAllQuery();
        query3.setReferenceClass(LargeProject.class);
        query3.useCursoredStream();
        query3.addJoinedAttribute(query3.getExpressionBuilder().get("teamLeader"));
        query3.addJoinedAttribute(query3.getExpressionBuilder().get("teamLeader").get("address"));
        test3.setQuery(query3);
        addTest(test3);

        addTest(new ReadObjectMappingJoinReadingTest());
        addTest(new MultipleJoinedAttributeQueryTest());
        addTest(new ComplexJoinedAttributeQueryTest());
    }

    public void addPartialTests() {
        // Partial objects
        ReadAllPartialReadingTest test3 = new ReadAllPartialReadingTest(12, "fisrtName");
        test3.setName("ReadAllPartialReadingTest-firstName,salary");
        ReadAllQuery query3 = new ReadAllQuery();
        query3.setReferenceClass(Employee.class);
        query3.dontMaintainCache();
        query3.addPartialAttribute("firstName");
        query3.addPartialAttribute("salary");
        test3.setQuery(query3);
        addTest(test3);

        ReadAllPartialReadingTest test4 = new ReadAllPartialReadingTest(1, "address");
        test4.setName("ReadAllPartialReadingTest-address,period");
        ReadAllQuery query4 = new ReadAllQuery();
        query4.setReferenceClass(Employee.class);
        query4.dontMaintainCache();
        query4.addPartialAttribute("address");
        query4.addPartialAttribute("period");
        query4.setSelectionCriteria(new org.eclipse.persistence.expressions.ExpressionBuilder().get("address").get("city").equal("Ottawa"));
        test4.setQuery(query4);
        addTest(test4);

        ReadAllPartialReadingTest test5 = new ReadAllPartialReadingTest(12, "city");
        test5.setName("ReadAllPartialReadingTest-city,salary");
        ReadAllQuery query5 = new ReadAllQuery();
        query5.setReferenceClass(Employee.class);
        query5.dontMaintainCache();
        query5.addPartialAttribute(query5.getExpressionBuilder().get("address").get("city"));
        query5.addPartialAttribute("salary");
        test5.setQuery(query5);
        addTest(test5);

        ReadAllPartialReadingTest test6 = new ReadAllPartialReadingTest(12, "city");
        test6.setName("ReadAllPartialReadingTest-city,salary-cursor");
        ReadAllQuery query6 = new ReadAllQuery();
        query6.useCursoredStream();
        query6.setReferenceClass(Employee.class);
        query6.dontMaintainCache();
        query6.addPartialAttribute(query6.getExpressionBuilder().get("address").get("city"));
        query6.addPartialAttribute("salary");
        test6.setQuery(query6);
        addTest(test6);

        ReadAllPartialReadingTest test1m = new ReadAllPartialReadingTest(12, "areaCode");
        test1m.setName("ReadAllPartialReadingTest-type-areaCode");
        ReadAllQuery query1m = new ReadAllQuery();
        query1m.setReferenceClass(Employee.class);
        query1m.dontMaintainCache();
        Expression phones = query1m.getExpressionBuilder().anyOf("phoneNumbers");
        query1m.addPartialAttribute(phones.get("id"));
        query1m.addPartialAttribute(phones.get("type"));
        query1m.addPartialAttribute(phones.get("areaCode"));
        test1m.setQuery(query1m);
        addTest(test1m);

        ReadAllTest test9 = new ReadAllTest(Employee.class, 12);
        test9.setName("ReadAllPartialReadingTest-PolicyMaxCoverage");
        ReadAllQuery query9 = new ReadAllQuery();
        query9.setReferenceClass(Employee.class);
        query9.dontMaintainCache();
        query9.addPartialAttribute("normalHours");
        //query9.addPartialAttribute("policyHolder");
        test9.setQuery(query9);
        addTest(test9);

        ReadAllPartialReadingTest test10 = new ReadAllPartialReadingTest(12, "id");
        test10.setName("ReadAllPartialReadingTest-id-SelectPrimaryKey");
        ReadAllQuery query10 = new ReadAllQuery();
        query10.setReferenceClass(Employee.class);
        query10.dontMaintainCache();
        query10.addPartialAttribute("id");
        test10.setQuery(query10);
        addTest(test10);

        ReadAllPartialReadingTest test11 = new ReadAllPartialReadingTest(12, "firstName");
        test11.setName("ReadAllPartialReadingTest-firstName-OrderByPrimaryKey");
        ReadAllQuery query11 = new ReadAllQuery();
        query11.setReferenceClass(Employee.class);
        query11.dontMaintainCache();
        query11.addPartialAttribute("firstName");
        query11.addAscendingOrdering("id");
        test11.setQuery(query11);
        addTest(test11);

        ReadAllPartialReadingTest test12 = new ReadAllPartialReadingTest(12, "id");
        test12.setName("ReadAllPartialReadingTest-firstName-SelectAndOrderByPrimaryKey");
        ReadAllQuery query12 = new ReadAllQuery();
        query12.setReferenceClass(Employee.class);
        query12.dontMaintainCache();
        query12.addPartialAttribute("id");
        query12.addAscendingOrdering("id");
        test12.setQuery(query12);
        addTest(test12);

        ReadAllPartialReadingAddressTest test14 = new ReadAllPartialReadingAddressTest(12, "id");
        test14.setName("ReadAllPartialReadingAddressTest - Address - SelectDistinctAndOrderByPrimaryKey");
        ReadAllQuery query14 = new ReadAllQuery();
        query14.setReferenceClass(Address.class);
        query14.dontMaintainCache();
        query14.addPartialAttribute("id");
        query14.addAscendingOrdering("id");
        query14.useDistinct();
        test14.setQuery(query14);
        addTest(test14);

        ReadAllPartialReadingAddressTest test15 = new ReadAllPartialReadingAddressTest(12, "id");
        test15.setName("ReadAllPartialReadingAddressTest - Employee - SelectAddressId");
        ReadAllQuery query15 = new ReadAllQuery();
        query15.setReferenceClass(Employee.class);
        query15.dontMaintainCache();
        query15.addPartialAttribute("id");
        query15.addPartialAttribute(new org.eclipse.persistence.expressions.ExpressionBuilder().get("address").get("id"));
        test15.setQuery(query15);
        addTest(test15);

        ReadAllPartialReadingAddressTest test16 = new ReadAllPartialReadingAddressTest(26, "id");
        test16.setName("ReadAllPartialReadingAddressTest - PhoneNumber - Employee - SelectAddressId");
        ReadAllQuery query16 = new ReadAllQuery();
        query16.setReferenceClass(PhoneNumber.class);
        query16.dontMaintainCache();
        query16.useDistinct();
        query16.addPartialAttribute(new org.eclipse.persistence.expressions.ExpressionBuilder().get("owner").get("address").get("id"));
        test16.setQuery(query16);
        addTest(test16);

        addTest(new QueryValidationTest());
    }

    @Override
    public void addTests() {
        addJoinTests();
        addBatchTests();
        addPartialTests();
        addTest(new ReadAllBindAllParametersTest());
        addTest(buildBatch1mTest());
    }

    public TestCase buildBatch1mTest() {
        TestCase test = new TestCase() {
            @Override
            public void test() {
                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();

                ReadAllQuery query = new ReadAllQuery();
                query.setReferenceClass(Employee.class);

                Expression rootExpression = query.getExpressionBuilder();

                Expression filterPart1 =
                 rootExpression.anyOfAllowingNone("phoneNumbers")
                   .getAllowingNull("owner").get("firstName").like("%");

                Expression filterPart2 =
                 rootExpression.anyOfAllowingNone("phoneNumbers")
                   .get("number").like("%");

                query.setSelectionCriteria(filterPart1.and(filterPart2));

                Expression expression = rootExpression.getAllowingNull("address");
                query.addBatchReadAttribute(expression);

                Expression expression2 = rootExpression.getAllowingNull("phoneNumbers");
                query.addBatchReadAttribute(expression2);

                List<Employee> result = (List<Employee>) getSession().executeQuery(query);
                result.get(0).getPhoneNumbers().size();

                getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
                for (Employee employee : result) {
                    if (!compareObjects(employee, getSession().readObject(employee))) {
                        throwError("Employeee does not match:" + employee);
                    }
                }
            }
        };
        test.setName("Batch1mTest");
        return test;
    }
}
