/*******************************************************************************
 * Copyright (c) 1998, 2013 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:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.testing.tests.queries;

import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.exceptions.*;

import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * For bug 3431017 tests when a NO_LOCK query joins an attribute which should be locked.
 * <p>
 * The correct behavior is that the object should be read again.
 */

public class PessimisticLockNoLockJoinedTest extends PessimisticLockJoinedAttributeTest {

public PessimisticLockNoLockJoinedTest() {
	this.lockMode = ObjectLevelReadQuery.LOCK_NOWAIT;
	setDescription("For bug 3431017 tests when a NO_LOCK query joins an attribute which should be locked.");
}
public void test () throws Exception
{
    if (!(getSession().getPlatform().isOracle() || getSession().getPlatform().isSQLServer())) {
		throw new TestWarningException("This test only runs on Oracle where writes do not block reads.");
	}
		
	uow = getSession().acquireUnitOfWork();

	ReadObjectQuery query = new ReadObjectQuery(LargeProject.class);
	// Only Charles Chanley and John Way are team leaders of projects they are also working on.
	Expression expression = query.getExpressionBuilder().get("teamLeader").get("firstName").equal("Charles");
	query.setSelectionCriteria(expression);
	query.addJoinedAttribute(query.getExpressionBuilder().get("teamLeader"));
	query.addJoinedAttribute(query.getExpressionBuilder().get("teamLeader").get("address"));

	// This is what differentiates from the super class test.
	query.setLockMode(ObjectLevelReadQuery.NO_LOCK);

	LargeProject uow1Project = (LargeProject)uow.executeQuery(query);

	uow1Project.getTeamLeader().getAddress();

	// Test the lock.
	// Because this is on a ServerSession the second UOW will have its own
	// ClientSession/exclusive connection.
	UnitOfWork uow2 = getSession().acquireUnitOfWork();
	try {
		boolean isLocked = false;
		LargeProject uow2Project = (LargeProject)uow2.executeQuery(query);

		try {
			uow2Project.getTeamLeader();
		} catch (EclipseLinkException exception) {
			isLocked = true;
		}
		if (!isLocked) {
			throw new TestWarningException("A joined attribute in an explicit NO_LOCK query is not being locked.  This breaks bug 3431017.");
		}
	} catch (RuntimeException e) {
		throw e;
	} finally {
		if (uow2 != null) {
			uow2.release();
		}
	}
}
}
