/*
* Copyright 2002-2005 the original author or authors.
*
* 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.springmodules.orm.ojb;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import junit.framework.TestCase;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
import org.apache.ojb.broker.accesslayer.LookupException;
import org.easymock.MockControl;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.UnexpectedRollbackException;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
/**
* @author Juergen Hoeller
* @since 08.07.2004
*/
public class PersistenceBrokerTransactionManagerTests extends TestCase {
protected void setUp() throws Exception {
Resource res = new ClassPathResource("OJB.properties");
System.setProperty("OJB.properties", res.getFile().getAbsolutePath());
}
public void testTransactionCommit() throws LookupException, SQLException {
MockControl pbControl = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb = (PersistenceBroker) pbControl.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
final Object entity = new Object();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb.serviceConnectionManager();
pbControl.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 2);
con.isReadOnly();
conControl.setReturnValue(false, 1);
pb.beginTransaction();
pbControl.setVoidCallable(1);
pb.delete(entity);
pbControl.setVoidCallable(1);
pb.commitTransaction();
pbControl.setVoidCallable(1);
pb.close();
pbControl.setReturnValue(true, 1);
pbControl.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
protected PersistenceBroker getPersistenceBroker() {
return pb;
}
};
TransactionTemplate tt = new TransactionTemplate(tm);
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
PersistenceBrokerTemplate pbt = new PersistenceBrokerTemplate();
pbt.delete(entity);
}
});
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
pbControl.verify();
cmControl.verify();
conControl.verify();
}
public void testTransactionRollback() throws LookupException, SQLException {
MockControl pbControl = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb = (PersistenceBroker) pbControl.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
final Object entity = new Object();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb.serviceConnectionManager();
pbControl.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 2);
con.setReadOnly(true);
conControl.setVoidCallable(1);
con.getTransactionIsolation();
conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED, 1);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
conControl.setVoidCallable(1);
con.isReadOnly();
conControl.setReturnValue(true, 1);
con.setReadOnly(false);
conControl.setVoidCallable(1);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conControl.setVoidCallable(1);
pb.beginTransaction();
pbControl.setVoidCallable(1);
pb.delete(entity);
pbControl.setVoidCallable(1);
pb.abortTransaction();
pbControl.setVoidCallable(1);
pb.close();
pbControl.setReturnValue(true, 1);
pbControl.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
protected PersistenceBroker getPersistenceBroker() {
return pb;
}
};
TransactionTemplate tt = new TransactionTemplate(tm);
tt.setReadOnly(true);
tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
PersistenceBrokerTemplate pbt = new PersistenceBrokerTemplate();
pbt.delete(entity);
status.setRollbackOnly();
}
});
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
pbControl.verify();
cmControl.verify();
conControl.verify();
}
public void testParticipatingTransactionWithCommit() throws LookupException, SQLException {
MockControl pbControl = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb = (PersistenceBroker) pbControl.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
final Object entity = new Object();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb.serviceConnectionManager();
pbControl.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 2);
con.isReadOnly();
conControl.setReturnValue(false, 1);
pb.beginTransaction();
pbControl.setVoidCallable(1);
pb.delete(entity);
pbControl.setVoidCallable(1);
pb.commitTransaction();
pbControl.setVoidCallable(1);
pb.close();
pbControl.setReturnValue(true, 1);
pbControl.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
protected PersistenceBroker getPersistenceBroker() {
return pb;
}
};
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
final TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
PersistenceBrokerTemplate pbt = new PersistenceBrokerTemplate();
pbt.delete(entity);
}
});
}
});
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
pbControl.verify();
cmControl.verify();
conControl.verify();
}
public void testParticipatingTransactionWithRollbackOnly() throws LookupException, SQLException {
MockControl pbControl = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb = (PersistenceBroker) pbControl.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
final Object entity = new Object();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb.serviceConnectionManager();
pbControl.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 2);
con.isReadOnly();
conControl.setReturnValue(false, 1);
pb.beginTransaction();
pbControl.setVoidCallable(1);
pb.delete(entity);
pbControl.setVoidCallable(1);
pb.abortTransaction();
pbControl.setVoidCallable(1);
pb.close();
pbControl.setReturnValue(true, 1);
pbControl.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
protected PersistenceBroker getPersistenceBroker() {
return pb;
}
};
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
final TransactionTemplate tt = new TransactionTemplate(tm);
try {
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
PersistenceBrokerTemplate pbt = new PersistenceBrokerTemplate();
pbt.delete(entity);
status.setRollbackOnly();
}
});
}
});
fail("Should have thrown UnexpectedRollbackException");
}
catch (UnexpectedRollbackException ex) {
// expected
}
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
pbControl.verify();
cmControl.verify();
conControl.verify();
}
public void testParticipatingTransactionWithRequiresNew() throws LookupException, SQLException {
MockControl pb1Control = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb1 = (PersistenceBroker) pb1Control.getMock();
MockControl pb2Control = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb2 = (PersistenceBroker) pb2Control.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb1.serviceConnectionManager();
pb1Control.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 4);
con.isReadOnly();
conControl.setReturnValue(false, 2);
pb1.beginTransaction();
pb1Control.setVoidCallable(1);
pb2.serviceConnectionManager();
pb2Control.setReturnValue(cm, 2);
pb2.beginTransaction();
pb2Control.setVoidCallable(1);
pb2.commitTransaction();
pb2Control.setVoidCallable(1);
pb2.close();
pb2Control.setReturnValue(true, 1);
pb1.commitTransaction();
pb1Control.setVoidCallable(1);
pb1.close();
pb1Control.setReturnValue(true, 1);
pb1Control.replay();
pb2Control.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
int counter = 0;
protected PersistenceBroker getPersistenceBroker() {
counter++;
return (counter > 1 ? pb2 : pb1);
}
};
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
final TransactionTemplate tt = new TransactionTemplate(tm);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
assertEquals(pb1, OjbFactoryUtils.getPersistenceBroker(tm.getPbKey(), false));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
assertEquals(pb2, OjbFactoryUtils.getPersistenceBroker(tm.getPbKey(), false));
}
});
assertEquals(pb1, OjbFactoryUtils.getPersistenceBroker(tm.getPbKey(), false));
}
});
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
pb1Control.verify();
pb2Control.verify();
cmControl.verify();
conControl.verify();
}
public void testExposeJdbcTransaction() throws LookupException, SQLException {
MockControl dsControl = MockControl.createControl(DataSource.class);
final DataSource ds = (DataSource) dsControl.getMock();
MockControl pbControl = MockControl.createControl(PersistenceBroker.class);
final PersistenceBroker pb = (PersistenceBroker) pbControl.getMock();
MockControl cmControl = MockControl.createControl(ConnectionManagerIF.class);
final ConnectionManagerIF cm = (ConnectionManagerIF) cmControl.getMock();
final Object entity = new Object();
MockControl conControl = MockControl.createControl(Connection.class);
Connection con = (Connection) conControl.getMock();
pb.serviceConnectionManager();
pbControl.setReturnValue(cm, 2);
cm.getConnection();
cmControl.setReturnValue(con, 2);
con.isReadOnly();
conControl.setReturnValue(false, 1);
pb.beginTransaction();
pbControl.setVoidCallable(1);
pb.delete(entity);
pbControl.setVoidCallable(1);
pb.commitTransaction();
pbControl.setVoidCallable(1);
pb.close();
pbControl.setReturnValue(true, 1);
dsControl.replay();
pbControl.replay();
cmControl.replay();
conControl.replay();
final PersistenceBrokerTransactionManager tm = new PersistenceBrokerTransactionManager() {
protected PersistenceBroker getPersistenceBroker() {
return pb;
}
};
tm.setDataSource(ds);
TransactionTemplate tt = new TransactionTemplate(tm);
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
tt.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread broker", TransactionSynchronizationManager.hasResource(tm.getPbKey()));
assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
PersistenceBrokerTemplate pbt = new PersistenceBrokerTemplate();
pbt.delete(entity);
}
});
assertTrue("Hasn't thread broker", !TransactionSynchronizationManager.hasResource(tm.getPbKey()));
assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
dsControl.verify();
pbControl.verify();
cmControl.verify();
conControl.verify();
}
protected void tearDown() {
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
}
}