blob: 658f242752b40a892dc4d081673b8fff6ae953c6 [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jdo.test;
import javax.jdo.JDOException;
import javax.jdo.JDOHelper;
import javax.jdo.JDOOptimisticVerificationException;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.pc.PCPoint;
import org.apache.jdo.test.util.AbstractTest;
import org.apache.jdo.test.util.JDORITestRunner;
/**
* Tests that we correctly verify instance values during an optimistic
* transaction. In this test we create instances, and then get their object
* id's. We then use those object id's to create objects in a second PM. We
* then modify the instances in the first PM, and commit them. Then modify the
* values in some of the instances in an optimistic transaction in the second
* PM, and commit: this should fail, and we should get an exception which
* contains two other exceptions, one for each of the instances which failed to
* verify.
*
* @author Dave Bristor
*/
public class Test_Optimistic extends AbstractTest {
/** */
public static void main(String args[]) {
JDORITestRunner.run(Test_Optimistic.class);
}
/**
* Inserts some number of objects in the database
*/
public void test() {
insertObjects();
}
// Gets an extent of points, and changes them.
protected void insertObjects() {
PersistenceManager pm1 = null;
PersistenceManager pm2 = null;
PersistenceManager pm3 = null;
Transaction tx1 = null;
Transaction tx2 = null;
Transaction tx3 = null;
try {
pm1 = pmf.getPersistenceManager();
tx1 = pm1.currentTransaction();
if (debug) logger.debug("\nINSERT");
tx1.setOptimistic(false);
tx1.begin();
PCPoint p1a = new PCPoint(3, 5);
pm1.makePersistent(p1a);
PCPoint p1b = new PCPoint(7, 9);
pm1.makePersistent(p1b);
PCPoint p1c = new PCPoint(4, 8);
pm1.makePersistent(p1c);
Object oid_1a = JDOHelper.getObjectId(p1a);
if (debug) logger.debug("p1a " + p1a + ", oid=" + oid_1a);
Object oid_1b = JDOHelper.getObjectId(p1b);
if (debug) logger.debug("p1b " + p1b + ", oid=" + oid_1b);
Object oid_1c = JDOHelper.getObjectId(p1c);
if (debug) logger.debug("p1c " + p1c + ", oid=" + oid_1c);
tx1.commit();
// Start tx2
pm2 = pmf.getPersistenceManager();
tx2 = pm2.currentTransaction();
tx2.setOptimistic(true);
tx2.begin();
PCPoint p2a = (PCPoint)pm2.getObjectById(oid_1a, true);
PCPoint p2b = (PCPoint)pm2.getObjectById(oid_1b, true);
PCPoint p2c = (PCPoint)pm2.getObjectById(oid_1c, true);
if (debug)
printValues("p1X made persistent, p2X from getObjectById(getObjectId) technique",
p1a, p1b, p1c, p2a, p2b, p2c);
tx1 = pm1.currentTransaction();
tx1.setOptimistic(false);
tx1.begin();
p1a.setX(555);
p1b.setX(123);
// p1c.setX(blah blah); // intentionally, we do *not* change p1c
tx1.commit();
if (debug)
printValues("after change in Tx1 to p1X",
p1a, p1b, p1c, p2a, p2b, p2c);
p2a.setY(new Integer(7890)); // This should fail to verify
p2b.setY(new Integer(1212)); // Ditto p2a
p2c.setY(new Integer(1357)); // This should succeed (but roll back)
if (debug)
printValues("after changes in Tx2 to p1a & p1b",
p1a, p1b, p1c, p2a, p2b, p2c);
try {
tx2.commit();
} catch (JDOException ex) {
if (ex instanceof JDOOptimisticVerificationException) {
JDOOptimisticVerificationException jex =
(JDOOptimisticVerificationException)ex;
Throwable nested[] = jex.getNestedExceptions();
if (nested.length == 2) {
// XXX This might be improved: it *could* be a datastore
// exception, but not one which is for the expected verify
// failure.
if (debug)
logger.debug("In optimistic transaction, caught expected exception");
} else {
fail("In optimistic transaction caught unexpected exception:" + ex);
}
} else {
fail("In optimistic transaction caught unexpected exception:" + ex);
}
try {
if (tx2.isActive()) {
// MBO: is this legal?
if (debug) {
logger.debug("Transaction tx2 active; rolling back");
printValues("before rollback",
p1a, p1b, p1c, p2a, p2b, p2c);
}
tx2.rollback();
} else {
if (debug) logger.debug("Transaction tx2 rolled back");
}
} catch (JDOUserException ex2) {
// MBO: might not be necessary, see above
fail("Can't rollback" + ex2);
}
} finally {
if (debug) printValues("finally", p1a, p1b, p1c, p2a, p2b, p2c);
assertPCPointEquals("In finally: unexpected value of p1a", 555, 5, p1a);
assertPCPointEquals("In finally: unexpected value of p1b", 123, 9, p1b);
assertPCPointEquals("In finally: unexpected value of p1c", 4, 8, p1c);
assertPCPointEquals("In finally: unexpected value of p2a", 3, 5, p2a);
assertPCPointEquals("In finally: unexpected value of p2b", 7, 9, p2b);
assertPCPointEquals("In finally: unexpected value of p2c", 4, 8, p2c);
}
pm3 = pmf.getPersistenceManager();
tx3 = pm3.currentTransaction();
tx3.setOptimistic(false);
tx3.begin();
PCPoint p3a = (PCPoint)pm3.getObjectById(oid_1a, false);
PCPoint p3b = (PCPoint)pm3.getObjectById(oid_1b, false);
PCPoint p3c = (PCPoint)pm3.getObjectById(oid_1c, false);
if (debug)
printValues("values labelled p2X are really p3X in this list",
p1a, p1b, p1c, p3a, p3b, p3c);
assertPCPointEquals("tx3: unexpected value of p1a", 555, 5, p1a);
assertPCPointEquals("tx3: unexpected value of p1b", 123, 9, p1b);
assertPCPointEquals("tx3: unexpected value of p1c", 4, 8, p1c);
assertPCPointEquals("tx3: unexpected value of p3a", 555, 5, p3a);
assertPCPointEquals("tx3: unexpected value of p3b", 123, 9, p3b);
assertPCPointEquals("tx3: unexpected value of p3c", 4, 8, p3c);
tx3.commit();
}
finally {
if (tx3 != null && tx3.isActive())
tx3.rollback();
if (pm3 != null && !pm3.isClosed())
pm3.close();
if (tx2 != null && tx2.isActive())
tx2.rollback();
if (pm2 != null && !pm2.isClosed())
pm2.close();
if (tx1 != null && tx1.isActive())
tx1.rollback();
if (pm1 != null && !pm1.isClosed())
pm1.close();
}
}
private void printValues(
String str, PCPoint p1a, PCPoint p1b, PCPoint p1c,
PCPoint p2a, PCPoint p2b, PCPoint p2c) {
logger.debug(str);
logger.debug("p1a: " + p1a);
logger.debug("p1b: " + p1b);
logger.debug("p1c: " + p1c);
logger.debug("p2a: " + p2a);
logger.debug("p2b: " + p2b);
logger.debug("p2c: " + p2c);
}
private void assertPCPointEquals(String msg, int x, int y, PCPoint actual)
{
assertEquals(msg + " field x", x, actual.getX());
assertEquals(msg + " field y", new Integer(y), actual.getY());
}
}