001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.test.entity.cmr;
017:
018: import org.apache.openejb.test.entity.cmr.onetomany.ArtistLocal;
019: import org.apache.openejb.test.entity.cmr.onetomany.ArtistLocalHome;
020: import org.apache.openejb.test.entity.cmr.onetomany.SongLocal;
021: import org.apache.openejb.test.entity.cmr.onetomany.SongLocalHome;
022: import org.apache.openejb.test.entity.cmr.onetomany.ArtistPk;
023: import org.apache.openejb.test.entity.cmr.onetomany.SongPk;
024:
025: import javax.ejb.FinderException;
026: import javax.ejb.CreateException;
027: import java.sql.Connection;
028: import java.sql.ResultSet;
029: import java.sql.Statement;
030: import java.sql.SQLException;
031: import java.util.HashSet;
032: import java.util.Set;
033: import java.util.Arrays;
034: import java.util.Iterator;
035: import java.util.ConcurrentModificationException;
036:
037: /**
038: * @version $Revision: 607077 $ $Date: 2007-12-27 06:55:23 -0800 $
039: */
040: public class OneToManyComplexPkTests extends AbstractCMRTest {
041: private ArtistLocalHome artistLocalHome;
042: private SongLocalHome songLocalHome;
043:
044: public OneToManyComplexPkTests() {
045: super ("OneToManyComplex.");
046: }
047:
048: protected void setUp() throws Exception {
049: super .setUp();
050:
051: artistLocalHome = (ArtistLocalHome) initialContext
052: .lookup("client/tests/entity/cmr/oneToMany/ComplexArtistLocal");
053: songLocalHome = (SongLocalHome) initialContext
054: .lookup("client/tests/entity/cmr/oneToMany/ComplexSongLocal");
055: }
056:
057: public void test00_AGetBExistingAB() throws Exception {
058: resetDB();
059: beginTransaction();
060: try {
061: ArtistLocal artist = findArtist(1);
062: Set bSet = artist.getPerformed();
063: assertEquals(2, bSet.size());
064: for (Object value : bSet) {
065: SongLocal song = (SongLocal) value;
066: if (song.getId().equals(11)) {
067: assertEquals("value11", song.getName());
068: } else if (song.getId().equals(22)) {
069: assertEquals("value22", song.getName());
070: } else {
071: fail();
072: }
073: }
074: } finally {
075: completeTransaction();
076: }
077: }
078:
079: public void test01_BGetAExistingAB() throws Exception {
080: resetDB();
081: beginTransaction();
082: try {
083: SongLocal song = findSong(11);
084: ArtistLocal artist = song.getPerformer();
085: assertNotNull(artist);
086: assertEquals(new Integer(1), artist.getId());
087: assertEquals("value1", artist.getName());
088:
089: song = findSong(22);
090: artist = song.getPerformer();
091: assertNotNull(artist);
092: assertEquals(new Integer(1), artist.getId());
093: assertEquals("value1", artist.getName());
094: } finally {
095: completeTransaction();
096: }
097: }
098:
099: public void test02_ASetBDropExisting() throws Exception {
100: resetDB();
101: beginTransaction();
102: try {
103: ArtistLocal artist = findArtist(1);
104: artist.setPerformed(new HashSet<SongLocal>());
105: } finally {
106: completeTransaction();
107: }
108: assertUnlinked(1);
109: }
110:
111: public void test03_BSetADropExisting() throws Exception {
112: resetDB();
113: beginTransaction();
114: try {
115: SongLocal song = findSong(11);
116: song.setPerformer(null);
117: song = findSong(22);
118: song.setPerformer(null);
119: } finally {
120: completeTransaction();
121: }
122:
123: assertUnlinked(1);
124: }
125:
126: public void test04_ASetBNewAB() throws Exception {
127: resetDB();
128: beginTransaction();
129: try {
130: ArtistLocal artist = findArtist(2);
131: SongLocal song = findSong(22);
132: Set<SongLocal> songSets = new HashSet<SongLocal>();
133: songSets.add(song);
134: artist.setPerformed(songSets);
135: } finally {
136: completeTransaction();
137: }
138:
139: assertLinked(2, 22);
140: }
141:
142: public void test05_BSetANewAB() throws Exception {
143: resetDB();
144: beginTransaction();
145: try {
146: ArtistLocal artist = findArtist(2);
147: SongLocal song = findSong(22);
148: song.setPerformer(artist);
149: } finally {
150: completeTransaction();
151: }
152: assertLinked(2, 22);
153: }
154:
155: public void test06_ASetBExistingBNewA() throws Exception {
156: resetDB();
157: beginTransaction();
158: try {
159: ArtistLocal artist = findArtist(2);
160: SongLocal song = findSong(11);
161: Set<SongLocal> songSets = artist.getPerformed();
162: songSets.add(song);
163: } finally {
164: completeTransaction();
165: }
166:
167: assertLinked(2, 11);
168: }
169:
170: public void test07_BSetAExistingBNewA() throws Exception {
171: resetDB();
172: beginTransaction();
173: try {
174: ArtistLocal artist = findArtist(2);
175: SongLocal song = findSong(11);
176: song.setPerformer(artist);
177: } finally {
178: completeTransaction();
179: }
180:
181: assertLinked(2, 11);
182: }
183:
184: public void test08_ASetBExistingANewB() throws Exception {
185: resetDB();
186: beginTransaction();
187: try {
188: ArtistLocal artist = findArtist(1);
189: SongLocal song = createSong(33);
190: Set<SongLocal> songSets = artist.getPerformed();
191: songSets.add(song);
192: } finally {
193: completeTransaction();
194: }
195: assertLinked(1, 11, 22, 33);
196: }
197:
198: public void test09_BSetAExistingANewB() throws Exception {
199: resetDB();
200: beginTransaction();
201: try {
202: ArtistLocal artist = findArtist(1);
203: SongLocal song = createSong(33);
204: song.setPerformer(artist);
205: } finally {
206: completeTransaction();
207: }
208:
209: assertLinked(1, 11, 22, 33);
210: }
211:
212: public void test10_RemoveRelationships() throws Exception {
213: resetDB();
214: beginTransaction();
215: try {
216: SongLocal song = findSong(11);
217: ArtistLocal artist = song.getPerformer();
218: Set<SongLocal> songs = artist.getPerformed();
219: assertTrue(songs.contains(song));
220: song.remove();
221: assertFalse(songs.contains(song));
222: } finally {
223: completeTransaction();
224: }
225: assertLinked(1, 22);
226: assertUnlinked(2);
227: }
228:
229: // uncomment when cmp to cmr is supported
230: public void TODO_testCMPMappedToForeignKeyColumn() throws Exception {
231: resetDB();
232: beginTransaction();
233: try {
234: SongLocal song = findSong(11);
235:
236: Integer field3 = song.getBpm();
237: assertEquals(song.getPerformer().getPrimaryKey(), field3);
238: } finally {
239: completeTransaction();
240: }
241: }
242:
243: // uncomment when cmp to cmr is supported
244: public void TODO_testSetCMPMappedToForeignKeyColumn()
245: throws Exception {
246: resetDB();
247: beginTransaction();
248: try {
249: SongLocal song = findSong(11);
250:
251: song.setBpm(2);
252:
253: ArtistLocal artist = song.getPerformer();
254: assertEquals(new Integer(2), artist.getId());
255: assertEquals("value2", artist.getName());
256: } finally {
257: completeTransaction();
258: }
259: }
260:
261: public void test11_Delete() throws Exception {
262: resetDB();
263:
264: beginTransaction();
265: try {
266: ArtistLocal artist = findArtist(1);
267: artist.setPerformed(new HashSet<SongLocal>());
268: Set<SongLocal> songs = artist.getComposed();
269: Set<SongLocal> bsCopies = new HashSet<SongLocal>(songs);
270: assertFalse(songs.isEmpty());
271: artist.remove();
272: assertTrue(songs.isEmpty());
273: for (SongLocal songLocal : bsCopies) {
274: assertNull(songLocal.getComposer());
275: }
276: } finally {
277: completeTransaction();
278: }
279: Connection c = ds.getConnection();
280: Statement s = c.createStatement();
281: ResultSet rs = s
282: .executeQuery("SELECT COUNT(*) FROM ComplexSong");
283: assertTrue(rs.next());
284: assertEquals(2, rs.getInt(1));
285: rs.close();
286: s.close();
287: c.close();
288: }
289:
290: public void test12_CascadeDelete() throws Exception {
291: resetDB();
292:
293: beginTransaction();
294: try {
295: ArtistLocal artist = findArtist(1);
296: Set<SongLocal> songs = artist.getPerformed();
297: assertFalse(songs.isEmpty());
298: artist.remove();
299: assertTrue(songs.isEmpty());
300: } finally {
301: completeTransaction();
302: }
303: Connection c = ds.getConnection();
304: Statement s = c.createStatement();
305: ResultSet rs = s
306: .executeQuery("SELECT COUNT(*) FROM ComplexSong");
307: assertTrue(rs.next());
308: assertEquals(0, rs.getInt(1));
309: rs.close();
310: s.close();
311: c.close();
312: }
313:
314: public void testIllegalCmrCollectionArgument() throws Exception {
315: resetDB();
316: beginTransaction();
317: try {
318: ArtistLocal artist = findArtist(new Integer(1));
319: Set songs = artist.getComposed();
320:
321: try {
322: songs.add(new Object());
323: fail("expected games.add(new Object()) to throw an IllegalArgumentException");
324: } catch (IllegalArgumentException e) {
325: }
326:
327: try {
328: songs.addAll(Arrays.asList(new Object()));
329: fail("expected games.addAll(Arrays.asList(new Object())) to throw an IllegalArgumentException");
330: } catch (IllegalArgumentException expected) {
331: }
332: } finally {
333: completeTransaction();
334: }
335: }
336:
337: public void testModifyCmrCollectionOusideTx() throws Exception {
338: resetDB();
339: beginTransaction();
340: Set songs;
341: SongLocal newSong;
342: try {
343: ArtistLocal artist = findArtist(new Integer(1));
344: newSong = createSong(new Integer(33));
345: songs = artist.getComposed();
346: } finally {
347: completeTransaction();
348: }
349:
350: // CMR collections should still be readable
351: assertFalse(songs.isEmpty());
352: assertEquals(2, songs.size());
353: for (Iterator iter = songs.iterator(); iter.hasNext();) {
354: SongLocal song = (SongLocal) iter.next();
355: if (song.getId().equals(new Integer(11))) {
356: assertEquals("value11", song.getName());
357: } else if (song.getId().equals(new Integer(22))) {
358: assertEquals("value22", song.getName());
359: } else {
360: fail();
361: }
362: }
363:
364: // But CMR collections should not be modifiable
365: try {
366: songs.add(newSong);
367: fail("expected songs.add(newSong) to throw an IllegalStateException");
368: } catch (IllegalStateException expected) {
369: }
370: try {
371: songs.addAll(Arrays.asList(newSong));
372: fail("expected songs.addAll(Arrays.asList(newSong)) to throw an IllegalStateException");
373: } catch (IllegalStateException expected) {
374: }
375: try {
376: songs.remove(newSong);
377: fail("expected songs.remove(newSong) to throw an IllegalStateException");
378: } catch (IllegalStateException expected) {
379: }
380: try {
381: songs.removeAll(Arrays.asList(newSong));
382: fail("expected songs.removeAll(Arrays.asList(newSong)) to throw an IllegalStateException");
383: } catch (IllegalStateException expected) {
384: }
385: Iterator iterator = songs.iterator();
386: try {
387: iterator.remove();
388: fail("expected iterator.remove() to throw an ConcurrentModificationException");
389: } catch (ConcurrentModificationException expected) {
390: }
391: }
392:
393: public void testModifyCmrCollectionInNewTx() throws Exception {
394: resetDB();
395: beginTransaction();
396: Set songs;
397: SongLocal newSong;
398: try {
399: ArtistLocal artist = findArtist(new Integer(1));
400: newSong = createSong(new Integer(33));
401: songs = artist.getComposed();
402: } finally {
403: completeTransaction();
404: }
405:
406: beginTransaction();
407: try {
408: // CMR collections should still be readable
409: assertFalse(songs.isEmpty());
410: assertEquals(2, songs.size());
411: for (Iterator iter = songs.iterator(); iter.hasNext();) {
412: SongLocal song = (SongLocal) iter.next();
413: if (song.getId().equals(new Integer(11))) {
414: assertEquals("value11", song.getName());
415: } else if (song.getId().equals(new Integer(22))) {
416: assertEquals("value22", song.getName());
417: } else {
418: fail();
419: }
420: }
421:
422: // But CMR collections should not be modifiable
423: try {
424: songs.add(newSong);
425: fail("expected songs.add(newSong) to throw an IllegalStateException");
426: } catch (IllegalStateException expected) {
427: }
428: try {
429: songs.addAll(Arrays.asList(newSong));
430: fail("expected songs.addAll(Arrays.asList(newSong)) to throw an IllegalStateException");
431: } catch (IllegalStateException expected) {
432: }
433: try {
434: songs.remove(newSong);
435: fail("expected songs.remove(newSong) to throw an IllegalStateException");
436: } catch (IllegalStateException expected) {
437: }
438: try {
439: songs.removeAll(Arrays.asList(newSong));
440: fail("expected songs.removeAll(Arrays.asList(newSong)) to throw an IllegalStateException");
441: } catch (IllegalStateException expected) {
442: }
443: Iterator iterator = songs.iterator();
444: try {
445: iterator.remove();
446: fail("expected iterator.remove() to throw an ConcurrentModificationException");
447: } catch (ConcurrentModificationException expected) {
448: }
449: } finally {
450: completeTransaction();
451: }
452: }
453:
454: public void testIteratorConcurrentModification() throws Exception {
455: resetDB();
456: beginTransaction();
457: try {
458: ArtistLocal artist = findArtist(new Integer(1));
459: SongLocal song = findSong(new Integer(11));
460: Set songs = artist.getComposed();
461: assertFalse(songs.isEmpty());
462: assertEquals(2, songs.size());
463:
464: Iterator iterator = songs.iterator();
465:
466: songs.remove(song);
467: assertEquals(1, songs.size());
468:
469: try {
470: iterator.next();
471: fail("expected iterator.next() to throw an ConcurrentModificationException");
472: } catch (ConcurrentModificationException expected) {
473: }
474: } finally {
475: completeTransaction();
476: }
477: }
478:
479: public void testIteratorAndRemove() throws Exception {
480: resetDB();
481: beginTransaction();
482: try {
483: ArtistLocal artist = findArtist(new Integer(1));
484: SongLocal song = findSong(new Integer(11));
485: Set games = artist.getComposed();
486: assertFalse(games.isEmpty());
487: assertEquals(2, games.size());
488:
489: Iterator iterator = games.iterator();
490:
491: assertTrue(games.contains(song));
492: artist.remove();
493: assertFalse(games.contains(song));
494: assertEquals(0, games.size());
495:
496: try {
497: iterator.next();
498: fail("expected iterator.next() to throw an ConcurrentModificationException");
499: } catch (ConcurrentModificationException expected) {
500: }
501: } finally {
502: completeTransaction();
503: }
504: }
505:
506: private ArtistLocal createArtist(int artistId)
507: throws CreateException {
508: ArtistLocal artist = artistLocalHome.create(new ArtistPk(
509: artistId, "value" + artistId));
510: return artist;
511: }
512:
513: private ArtistLocal findArtist(int artistId) throws FinderException {
514: return artistLocalHome.findByPrimaryKey(new ArtistPk(artistId,
515: "value" + artistId));
516: }
517:
518: private SongLocal createSong(int songId) throws CreateException {
519: SongLocal song = songLocalHome.create(new SongPk(songId,
520: "value" + songId));
521: return song;
522: }
523:
524: private SongLocal findSong(int songId) throws FinderException {
525: return songLocalHome.findByPrimaryKey(new SongPk(songId,
526: "value" + songId));
527: }
528:
529: private void assertLinked(int artistId, int... songIds)
530: throws Exception {
531: Connection c = ds.getConnection();
532: Statement s = c.createStatement();
533: ResultSet rs = s
534: .executeQuery("SELECT name FROM ComplexArtist WHERE id = "
535: + artistId);
536: assertTrue(rs.next());
537: assertEquals("value" + artistId, rs.getString("name"));
538: close(rs);
539:
540: // assert that there we are looking for the same number of linked beans
541: rs = s
542: .executeQuery("SELECT COUNT(*) FROM ComplexSong WHERE performer_id = 1");
543: assertTrue(rs.next());
544: assertEquals(songIds.length, rs.getInt(1));
545: rs.close();
546:
547: // assert each of the listed b pks is linked to a
548: for (int songId : songIds) {
549: rs = s
550: .executeQuery("SELECT name, performer_id FROM ComplexSong WHERE id = "
551: + songId);
552: assertTrue(rs.next());
553: assertEquals("value" + songId, rs.getString("name"));
554: assertEquals(artistId, rs.getInt("performer_id"));
555: close(rs);
556: }
557: close(s);
558: close(c);
559: }
560:
561: private void assertUnlinked(int aPk) throws Exception {
562: Connection c = ds.getConnection();
563: Statement s = c.createStatement();
564: ResultSet rs = s
565: .executeQuery("SELECT COUNT(*) FROM ComplexSong WHERE performer_id = "
566: + aPk);
567: assertTrue(rs.next());
568: assertEquals(0, rs.getInt(1));
569: close(rs);
570: close(s);
571: close(c);
572: }
573:
574: private void resetDB() throws Exception {
575: Connection connection = ds.getConnection();
576: Statement statement = null;
577: try {
578: statement = connection.createStatement();
579:
580: try {
581: statement.execute("DELETE FROM ComplexArtist");
582: } catch (SQLException ignored) {
583: }
584: try {
585: statement.execute("DELETE FROM ComplexSong");
586: } catch (SQLException ignored) {
587: }
588: } finally {
589: close(statement);
590: close(connection);
591: }
592:
593: ArtistLocal artist1 = createArtist(1);
594: createArtist(2);
595:
596: SongLocal song1 = createSong(11);
597: SongLocal song2 = createSong(22);
598:
599: song1.setPerformer(artist1);
600: song2.setPerformer(artist1);
601:
602: song1.setComposer(artist1);
603: song2.setComposer(artist1);
604: }
605:
606: protected void dump() throws SQLException {
607: dumpTable(ds, "ComplexArtist");
608: dumpTable(ds, "ComplexSong");
609: }
610: }
|