001: package org.apache.ojb.odmg;
002:
003: import java.util.List;
004:
005: import org.apache.ojb.broker.Identity;
006: import org.apache.ojb.junit.ODMGTestCase;
007: import org.apache.ojb.odmg.shared.Person;
008: import org.apache.ojb.odmg.shared.PersonImpl;
009: import org.apache.ojb.odmg.shared.Site;
010: import org.odmg.Implementation;
011: import org.odmg.OQLQuery;
012: import org.odmg.Transaction;
013: import org.odmg.TransactionNotInProgressException;
014:
015: /**
016: * Collection of test cases sent by OJB users
017: *
018: * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
019: * @version $Id: UserTestCases.java,v 1.13.2.4 2005/06/04 14:48:05 arminw Exp $
020: */
021: public class UserTestCases extends ODMGTestCase {
022: public static void main(String[] args) {
023: String[] arr = { UserTestCases.class.getName() };
024: junit.textui.TestRunner.main(arr);
025: }
026:
027: /**
028: * Send by Antonio
029: * Note: The name attribute was declared as
030: * unique in the DB.
031: */
032: public void testDuplicateInsertion() throws Exception {
033: String name = "testDuplicateInsertion_"
034: + System.currentTimeMillis();
035: String nameNew = "testDuplicateInsertion_New_"
036: + System.currentTimeMillis();
037:
038: //System.out.println("TEST: Database open");
039:
040: // insert an object with UNIQUE field NAME="A site"
041: //System.out.println("TEST: Insert first object");
042: newSite(odmg, name, 2, 1);
043:
044: // insert another object with UNIQUE field NAME="A site"
045: // This should not create a new object (UNIQUE fields conflict) but
046: // should resume gracefuly
047: //System.out.println("TEST: Insert second object, should fail");
048: try {
049: newSite(odmg, name, 3, 2);
050: assertTrue(
051: "We should get a SqlException 'Violation of unique index'",
052: false);
053: } catch (Exception e) {
054: // we wait for this exception
055: assertTrue(true);
056: }
057:
058: // insert an object with new UNIQUE field NAME
059: // should always work
060: //System.out.println("TEST: Insert third object");
061: try {
062: newSite(odmg, nameNew, 1, 2);
063: assertTrue(true);
064: } catch (Exception e) {
065: e.printStackTrace();
066: assertTrue("This exception should not happend: "
067: + e.getMessage(), false);
068: throw e;
069: }
070: //System.out.println("TEST: Database closed");
071: }
072:
073: private void newSite(Implementation odmg, String name, int year,
074: int semester) throws Exception {
075: Transaction tx = null;
076: tx = odmg.newTransaction();
077: Site site = null;
078: tx.begin();
079:
080: site = new Site();
081: site.setName(name);
082: site.setYear(new Integer(year));
083: site.setSemester(new Integer(semester));
084:
085: tx.lock(site, Transaction.WRITE);
086: tx.commit();
087: }
088:
089: public void testSimpleQueryDelete() throws Exception {
090: String name = "testSimpleQueryDelete - "
091: + System.currentTimeMillis();
092:
093: Site site = new Site();
094: site.setName(name);
095: Transaction tx = odmg.newTransaction();
096: tx.begin();
097: tx.lock(site, Transaction.WRITE);
098: tx.commit();
099:
100: OQLQuery query = odmg.newOQLQuery();
101: query.create("select sites from " + Site.class.getName()
102: + " where name=$1");
103: query.bind(name);
104: tx.begin();
105: List result = (List) query.execute();
106: if (result.size() == 0) {
107: fail("Stored object not found");
108: }
109: tx.commit();
110:
111: tx.begin();
112: database.deletePersistent(site);
113: tx.commit();
114:
115: query = odmg.newOQLQuery();
116: query.create("select sites from " + Site.class.getName()
117: + " where name=$1");
118: query.bind(name);
119: tx.begin();
120: List result2 = (List) query.execute();
121: if (result2.size() > 0) {
122: fail("We should not found deleted objects");
123: }
124: tx.commit();
125: }
126:
127: /**
128: * User test case posted by Charles:
129: * <p/>
130: * Up to now, we've been just using the broker layer. I now have a usecase
131: * where we will need to use the ODMG layer. We do not want to use implicit
132: * locking; I want my developers to explicit lock each object to an ODMG
133: * transaction (implicit locking generates loads of queries for all the proxy
134: * collections - should be fixed since OJB1.0.3).
135: * <p/>
136: * It seems that something 'funny' happens if implicit locking is turned off -
137: * objects are not marked as being "dirty" when changed - even when they are
138: * explicitly lock to the transaction.
139: * <p/>
140: * As I am a complete novice in the ways of the ODMG, I don't really know where
141: * to look to sort this issue out so I have added a new test method to
142: * org.apache.ojb.odmg.UserTestCases (it should be attached to this email).
143: * Essentially, it creates an object and persists it; retrieves and updates it;
144: * then flushes the cache, and retrieves it again to ensure the update worked.
145: * If ImplicitLocking is TRUE, the test passes. If ImplicitLocking is FALSE,
146: * the test fails.
147: * <p/>
148: * I think this is incorrect, and would dearly like this to be resolved.
149: * <p/>
150: * thma's comment: IMO this works as designed. objects must be locked to
151: * an ODMG tx before any modifications are taking place.
152: * I simply moved the lock two lines up and the test passed.
153: */
154: public void testImplicitLocking() throws Exception {
155: String name = "testImplicitLocking - "
156: + System.currentTimeMillis();
157: String queryString = "select sites from "
158: + Site.class.getName() + " where name = $1";
159:
160: /* Create an object */
161: Site site = new Site();
162: site.setName(name);
163:
164: TransactionExt tx = (TransactionExt) odmg.newTransaction();
165: // disable implicit locking for this tx instance
166: // this setting was used for the life-time of the tx instance
167: tx.setImplicitLocking(false);
168: tx.begin();
169: database.makePersistent(site);
170: tx.commit();
171:
172: /* Retrieve from the object created, and set the year*/
173: OQLQuery query = odmg.newOQLQuery();
174: query.create(queryString);
175: query.bind(name);
176:
177: tx.begin();
178: List result = (List) query.execute();
179: assertEquals(1, result.size());
180: site = (Site) result.get(0);
181: assertNotNull(site);
182: assertNull(site.getYear());
183: tx.lock(site, Transaction.WRITE);
184: site.setYear(new Integer(2003));
185: tx.commit();
186:
187: /* Flush the cache, and retrieve the object again */
188: query = odmg.newOQLQuery();
189: query.create(queryString);
190: query.bind(name);
191: tx.begin();
192: tx.getBroker().clearCache();
193: result = (List) query.execute();
194: assertEquals(1, result.size());
195: site = (Site) result.get(0);
196: assertNotNull(site);
197: assertNotNull("year should not be null", site.getYear());
198: tx.commit();
199: }
200:
201: /**
202: * store an object and then retrieve it by id.
203: */
204: public void testStoreRetrieveSameTxn() throws Exception {
205: String name = "testStoreRetrieveSameTxn_"
206: + System.currentTimeMillis();
207: Person mum = new PersonImpl();
208: mum.setFirstname(name);
209:
210: TransactionExt txn = (TransactionExt) odmg.newTransaction();
211: txn.begin();
212: txn.lock(mum, Transaction.WRITE);
213: // System.out.println("locked for write: " + mum);
214: txn.commit();
215:
216: txn.begin();
217: txn.getBroker().clearCache();
218: Identity mumId = txn.getBroker().serviceIdentity()
219: .buildIdentity(mum);
220: Person mum2 = (Person) txn.getBroker().getObjectByIdentity(
221: mumId);
222: // System.out.println("retrieved: " + mum2);
223: txn.commit();
224: assertNotNull(mum2);
225: assertEquals(name, mum2.getFirstname());
226: }
227:
228: public void testRetrieveNonExistent() {
229: try {
230: TransactionExt tx = (TransactionExt) odmg.newTransaction();
231: tx.begin();
232: // construct an id that does not exist in the database
233: Identity id = tx.getBroker().serviceIdentity()
234: .buildIdentity(PersonImpl.class, new Integer(-1));
235: tx.getBroker().getObjectByIdentity(id);
236: tx.abort();
237: } catch (Exception exc) {
238: exc.printStackTrace();
239: fail("caught unexpected exception: " + exc.toString());
240: }
241: }
242:
243: /**
244: * Not recommended to use such a construct!!!
245: */
246: public void testRetrieveOutsideTxn() {
247: try {
248: // construct an id that does not exist in the database
249: Identity id = new Identity(Person.class, Person.class,
250: new Integer[] { new Integer(-1) });
251: TransactionImpl txn = (TransactionImpl) odmg
252: .newTransaction();
253: try {
254: txn.getObjectByIdentity(id);
255: fail("expected TransactionNotInProgressException not thrown");
256: } catch (TransactionNotInProgressException exc) {
257: // expected.
258: }
259: } catch (Exception exc) {
260: exc.printStackTrace();
261: fail("caught unexpected exception: " + exc.toString());
262: }
263: }
264: }
|