/******************************************************************************* * Copyright (c) 1998, 2015 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 v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * dminsky - initial API and implementation ******************************************************************************/ package org.eclipse.persistence.testing.tests.queries; import org.eclipse.persistence.testing.framework.*; import org.eclipse.persistence.testing.models.insurance.*; import org.eclipse.persistence.descriptors.invalidation.*; import org.eclipse.persistence.internal.helper.*; import org.eclipse.persistence.descriptors.*; import org.eclipse.persistence.expressions.*; import org.eclipse.persistence.mappings.*; import org.eclipse.persistence.sessions.*; /** * EL Bug 245448 - Add regression tests for querying across relationships using * nested joining and DailyCacheInvalidationPolicy * - testing nested joining * - no indirection throughout * - daily expiration policy for cache invalidation * - foreign reference relationship on 1:M with batching + private owned * - 1:1 back-pointer for above not private owned, no batching, no joining */ public class QueryExecutionTimeSetOnBuildObjectTest extends TransactionalTestCase { protected QuerySQLTracker sqlTracker; private CacheInvalidationPolicy oldHolderCacheInvalidationPolicy; private boolean oldPoliciesShouldBatchRead; private boolean oldPoliciesShouldBePrivateOwned; private boolean oldPolicyHolderShouldBeBatchRead; private boolean oldPolicyHolderShouldBePrivateOwned; private int oldPolicyHolderJoining; private boolean oldAddressShouldBeBatchRead; private boolean oldAddressShouldBePrivateOwned; private int oldAddressJoining; public QueryExecutionTimeSetOnBuildObjectTest() { super(); setDescription("Test that no duplicate sql is generated for nested join queries without indirection"); } public void setup() { super.setup(); getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); ClassDescriptor holderDescriptor = getSession().getDescriptor(PolicyHolder.class); ClassDescriptor policyDescriptor = getSession().getDescriptor(Policy.class); ClassDescriptor addressDescriptor = getSession().getDescriptor(Address.class); // cache invalidation oldHolderCacheInvalidationPolicy = holderDescriptor.getCacheInvalidationPolicy(); holderDescriptor.setCacheInvalidationPolicy(new DailyCacheInvalidationPolicy(0, 0, 0, 0)); // PolicyHolder -> Policies batch reading OneToManyMapping policyHolderToPoliciesMapping = (OneToManyMapping) holderDescriptor.getMappingForAttributeName("policies"); oldPoliciesShouldBatchRead = policyHolderToPoliciesMapping.shouldUseBatchReading(); policyHolderToPoliciesMapping.setUsesBatchReading(true); // PolicyHolder -> Policies private owned oldPoliciesShouldBePrivateOwned = policyHolderToPoliciesMapping.isPrivateOwned(); policyHolderToPoliciesMapping.setIsPrivateOwned(true); // Policy -> PolicyHolder batch reading OneToOneMapping policyToPolicyHolderMapping = (OneToOneMapping) policyDescriptor.getMappingForAttributeName("policyHolder"); oldPolicyHolderShouldBeBatchRead = policyToPolicyHolderMapping.shouldUseBatchReading(); policyToPolicyHolderMapping.setUsesBatchReading(false); // Policy -> PolicyHolder private owned oldPolicyHolderShouldBePrivateOwned = policyToPolicyHolderMapping.isPrivateOwned(); policyToPolicyHolderMapping.setIsPrivateOwned(false); // Policy -> PolicyHolder joining oldPolicyHolderJoining = policyToPolicyHolderMapping.getJoinFetch(); policyToPolicyHolderMapping.setJoinFetch(ForeignReferenceMapping.NONE); policyToPolicyHolderMapping.getDescriptor().reInitializeJoinedAttributes(); // Address -> PolicyHolder batch reading OneToOneMapping addressToPolicyHolderMapping = (OneToOneMapping)addressDescriptor.getMappingForAttributeName("policyHolder"); oldAddressShouldBeBatchRead = addressToPolicyHolderMapping.shouldUseBatchReading(); addressToPolicyHolderMapping.setUsesBatchReading(false); // Address -> PolicyHolder joining oldAddressJoining = addressToPolicyHolderMapping.getJoinFetch(); addressToPolicyHolderMapping.setJoinFetch(ForeignReferenceMapping.INNER_JOIN); // joining must be enabled on Address -> PolicyHolder addressToPolicyHolderMapping.getDescriptor().reInitializeJoinedAttributes(); // Address -> PolicyHolder private owned oldAddressShouldBePrivateOwned = addressToPolicyHolderMapping.isPrivateOwned(); addressToPolicyHolderMapping.setIsPrivateOwned(false); PolicyHolder holder = new PolicyHolder(); holder.setFirstName("David"); holder.setLastName("Minkoff"); holder.setMale(); holder.setSsn(515376); holder.setBirthDate(Helper.dateFromString("1979/03/25")); holder.setOccupation("Electrician"); Address address = new Address(); address.setCity("Calgary"); address.setCountry("Canada"); address.setState("AB"); address.setStreet("Suite 840, 401 - 9th Avenue SW"); address.setZipCode("T2P3C5"); HealthPolicy healthPolicy1 = new HealthPolicy(); healthPolicy1.setPolicyNumber(515377); healthPolicy1.setDescription("policy 1"); healthPolicy1.setCoverageRate((float)1.5); healthPolicy1.setMaxCoverage(50000); HealthPolicy healthPolicy2 = new HealthPolicy(); healthPolicy2.setPolicyNumber(515378); healthPolicy2.setDescription("policy 2"); healthPolicy2.setCoverageRate((float)1.5); healthPolicy2.setMaxCoverage(50000); HealthPolicy healthPolicy3 = new HealthPolicy(); healthPolicy3.setPolicyNumber(515379); healthPolicy3.setDescription("policy 3"); healthPolicy3.setCoverageRate((float)1.5); healthPolicy3.setMaxCoverage(50000); holder.setAddress(address); holder.addPolicy(healthPolicy1); holder.addPolicy(healthPolicy2); holder.addPolicy(healthPolicy3); UnitOfWork uow = getSession().acquireUnitOfWork(); uow.registerObject(holder); uow.commit(); // create tracker object for query sql sqlTracker = new QuerySQLTracker(getSession()); getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); } public void test() { // query from address -> policyHolder -> Policy to trigger nested joins (no indirection) UnitOfWork uow = getSession().acquireUnitOfWork(); Expression expression = new ExpressionBuilder().get("zipCode").equal("T2P3C5"); uow.readObject(Address.class, expression); uow.release(); } public void verify() { // Insurance model expected SQL with configured adjustments in setup() // 1 x main select with joining from address -> policyholder // SELECT t1.CITY, t1.ZIPCODE, t1.STATE, t1.COUNTRY, t1.STREET, t1.SSN, t0.SSN, t0.L_NAME, t0.OCC, t0.BDATE, t0.F_NAME, t0.SEX FROM HOLDER t0, INS_ADDR t1 WHERE ((t1.ZIPCODE = T2P3C5) AND (t0.SSN = t1.SSN)) // 1x policy type inheritance query // SELECT DISTINCT POL_TYPE FROM POLICY WHERE (SSN = 515376) // 1 x policy select based on type from policy inheritance query and policyholder pk // SELECT POL_ID, POL_TYPE, MAX_COV, DESCRIPT, SSN, COV_RATE FROM POLICY WHERE ((SSN = 515376) AND (POL_TYPE = 2)) // 3 x claim selects from 3 policies read previously (no joining or batch reading configured) // SELECT DISTINCT CLM_TYPE FROM CLAIM WHERE (POL_ID = 515378) // SELECT DISTINCT CLM_TYPE FROM CLAIM WHERE (POL_ID = 515379) // SELECT DISTINCT CLM_TYPE FROM CLAIM WHERE (POL_ID = 515377) // 1 x PolicyHolder -> Child select (as mapped) // SELECT t0.CHILD_NAME FROM CHILDNAM t0 WHERE (t0.HOLDER_ID = 515376) // 1 x PolicyHolder -> Phone select (as mapped) // SELECT TYPE, PHONE_NUMBER, AREACODE FROM INS_PHONE WHERE (HOLDER_SSN = 515376) // = 8 statements expected int expectedNumberOfStatements = 8; int actualNumberOfSQLStatements = sqlTracker.getSqlStatements().size(); if (expectedNumberOfStatements != actualNumberOfSQLStatements) { throw new TestErrorException("Expected " + expectedNumberOfStatements + " SQL statements - got " + actualNumberOfSQLStatements); } } public void reset() { super.reset(); ClassDescriptor holderDescriptor = getSession().getDescriptor(PolicyHolder.class); ClassDescriptor policyDescriptor = getSession().getDescriptor(Policy.class); ClassDescriptor addressDescriptor = getSession().getDescriptor(Address.class); // cache invalidation oldHolderCacheInvalidationPolicy = holderDescriptor.getCacheInvalidationPolicy(); holderDescriptor.setCacheInvalidationPolicy(oldHolderCacheInvalidationPolicy); // PolicyHolder -> Policies batch reading OneToManyMapping policiesMapping = (OneToManyMapping) holderDescriptor.getMappingForAttributeName("policies"); policiesMapping.setUsesBatchReading(oldPoliciesShouldBatchRead); // PolicyHolder -> Policies private owned policiesMapping.setIsPrivateOwned(oldPoliciesShouldBePrivateOwned); // Policy -> PolicyHolder batch reading OneToOneMapping policyHolderMapping = (OneToOneMapping) policyDescriptor.getMappingForAttributeName("policyHolder"); policyHolderMapping.setUsesBatchReading(oldPolicyHolderShouldBeBatchRead); // Policy -> PolicyHolder private owned policyHolderMapping.setIsPrivateOwned(oldPolicyHolderShouldBePrivateOwned); // Policy -> PolicyHolder joining policyHolderMapping.setJoinFetch(oldPolicyHolderJoining); policyHolderMapping.getDescriptor().reInitializeJoinedAttributes(); // Address -> PolicyHolder batch reading OneToOneMapping addressToPolicyHolderMapping = (OneToOneMapping)addressDescriptor.getMappingForAttributeName("policyHolder"); addressToPolicyHolderMapping.setUsesBatchReading(oldAddressShouldBeBatchRead); // Address -> PolicyHolder joining addressToPolicyHolderMapping.setJoinFetch(oldAddressJoining); addressToPolicyHolderMapping.getDescriptor().reInitializeJoinedAttributes(); // Address -> PolicyHolder private owned addressToPolicyHolderMapping.setIsPrivateOwned(oldAddressShouldBePrivateOwned); sqlTracker.remove(); } }