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