/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.openejb.test.entity.cmr; import org.apache.openejb.test.entity.cmr.manytomany.GameLocal; import org.apache.openejb.test.entity.cmr.manytomany.GameLocalHome; import org.apache.openejb.test.entity.cmr.manytomany.GamePk; import org.apache.openejb.test.entity.cmr.manytomany.PlatformLocal; import org.apache.openejb.test.entity.cmr.manytomany.PlatformLocalHome; import org.apache.openejb.test.entity.cmr.manytomany.PlatformPk; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.ejb.TransactionRolledbackLocalException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * @version $Revision$ $Date$ */ public class ManyToManyComplexPkTests extends AbstractCMRTest { private PlatformLocalHome platformLocalHome; private GameLocalHome gameLocalHome; public ManyToManyComplexPkTests() { super("ManyToManyComplex."); } protected void setUp() throws Exception { super.setUp(); platformLocalHome = (PlatformLocalHome) initialContext.lookup("client/tests/entity/cmr/manyToMany/ComplexPlatformLocal"); gameLocalHome = (GameLocalHome) initialContext.lookup("client/tests/entity/cmr/manyToMany/ComplexGameLocal"); } public void testAGetBExistingAB() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); final Set<GameLocal> gameSets = platform.getGames(); assertEquals(2, gameSets.size()); for (final Iterator iter = gameSets.iterator(); iter.hasNext(); ) { final GameLocal game = (GameLocal) iter.next(); if (game.getId().equals(new Integer(11))) { assertEquals("value11", game.getName()); } else if (game.getId().equals(new Integer(22))) { assertEquals("value22", game.getName()); } else { fail(); } } } finally { completeTransaction(); } } public void testSetCmrNull() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); try { platform.setGames(null); fail("expected platform.setGames(null) to throw an IllegalArgumentException"); } catch (final TransactionRolledbackLocalException e) { final Throwable cause = e.getCause(); assertNotNull("cause is null", cause); assertTrue("cause is not a instance of IllegalArgumentException", cause instanceof IllegalArgumentException); } } finally { completeTransaction(); } } public void testBGetAExistingAB() throws Exception { resetDB(); beginTransaction(); try { final GameLocal game = findGame(new Integer(22)); final Set aSet = game.getPlatforms(); assertEquals(3, aSet.size()); for (final Iterator iter = aSet.iterator(); iter.hasNext(); ) { final PlatformLocal platform = (PlatformLocal) iter.next(); if (platform.getId().equals(new Integer(1))) { assertEquals("value1", platform.getName()); } else if (platform.getId().equals(new Integer(2))) { assertEquals("value2", platform.getName()); } else if (platform.getId().equals(new Integer(3))) { assertEquals("value3", platform.getName()); } else { fail(); } } } finally { completeTransaction(); } } public void testASetBDropExisting() throws Exception { resetDB(); beginTransaction(); try { PlatformLocal platform = findPlatform(new Integer(1)); platform.setGames(new HashSet<GameLocal>()); platform = findPlatform(new Integer(2)); platform.setGames(new HashSet<GameLocal>()); platform = findPlatform(new Integer(3)); platform.setGames(new HashSet<GameLocal>()); } finally { completeTransaction(); } assertAllUnlinked(); } public void testBSetADropExisting() throws Exception { resetDB(); beginTransaction(); try { GameLocal game = findGame(new Integer(11)); game.setPlatforms(new HashSet<PlatformLocal>()); game = findGame(new Integer(22)); game.setPlatforms(new HashSet<PlatformLocal>()); } finally { completeTransaction(); } assertAllUnlinked(); } public void testASetBNewAB() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = createPlatform(new Integer(4)); final GameLocal game = createGame(new Integer(33)); final Set<GameLocal> gameSets = platform.getGames(); gameSets.add(game); } finally { completeTransaction(); } assertLinked(4, 33); } public void testBSetANewAB() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = createPlatform(new Integer(4)); final GameLocal game = createGame(new Integer(33)); final Set<PlatformLocal> platformSets = game.getPlatforms(); platformSets.add(platform); } finally { completeTransaction(); } assertLinked(4, 33); } public void testASetBExistingBNewA() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = createPlatform(new Integer(4)); final GameLocal game = findGame(new Integer(11)); final Set<GameLocal> gameSets = platform.getGames(); gameSets.add(game); } finally { completeTransaction(); } assertLinked(4, 11); } public void testBSetAExistingBNewA() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = createPlatform(new Integer(4)); final GameLocal game = findGame(new Integer(11)); final Set<PlatformLocal> platformSets = game.getPlatforms(); platformSets.add(platform); } finally { completeTransaction(); } assertLinked(4, 11); } public void testASetBExistingANewB() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); final GameLocal game = createGame(new Integer(33)); final Set<GameLocal> gameSets = platform.getGames(); gameSets.add(game); } finally { completeTransaction(); } assertLinked(1, 33); } public void testBSetAExistingANewB() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); final GameLocal game = createGame(new Integer(33)); final Set<PlatformLocal> platformSets = game.getPlatforms(); platformSets.add(platform); } finally { completeTransaction(); } assertLinked(1, 33); } public void testRemoveRelationships() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); platform.remove(); } finally { completeTransaction(); } assertPlatformDeleted(1); } public void testIllegalCmrCollectionArgument() throws Exception { resetDB(); beginTransaction(); try { final PlatformLocal platform = findPlatform(new Integer(1)); final Set games = platform.getGames(); try { games.add(new Object()); fail("expected games.add(new Object()) to throw an IllegalArgumentException"); } catch (final IllegalArgumentException e) { } try { games.addAll(Arrays.asList(new Object())); fail("expected games.addAll(Arrays.asList(new Object())) to throw an IllegalArgumentException"); } catch (final IllegalArgumentException expected) { } } finally { completeTransaction(); } } public void testModifyCmrCollectionOusideTx() throws Exception { resetDB(); beginTransaction(); Set games; GameLocal newGame; try { final PlatformLocal platform = findPlatform(new Integer(1)); newGame = createGame(new Integer(33)); games = platform.getGames(); } finally { completeTransaction(); } // CMR collections should still be readable assertFalse(games.isEmpty()); assertEquals(2, games.size()); for (final Iterator iter = games.iterator(); iter.hasNext(); ) { final GameLocal game = (GameLocal) iter.next(); if (game.getId().equals(new Integer(11))) { assertEquals("value11", game.getName()); } else if (game.getId().equals(new Integer(22))) { assertEquals("value22", game.getName()); } else { fail(); } } // But CMR collections should not be modifiable try { games.add(newGame); fail("expected games.add(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.addAll(Arrays.asList(newGame)); fail("expected games.addAll(Arrays.asList(game)) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.remove(newGame); fail("expected games.remove(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.removeAll(Arrays.asList(newGame)); fail("expected games.removeAll(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } final Iterator iterator = games.iterator(); try { iterator.remove(); fail("expected iterator.remove() to throw an ConcurrentModificationException"); } catch (final ConcurrentModificationException expected) { } } public void testModifyCmrCollectionInNewTx() throws Exception { resetDB(); beginTransaction(); Set games; GameLocal newGame; try { final PlatformLocal platform = findPlatform(new Integer(1)); newGame = createGame(new Integer(33)); games = platform.getGames(); } finally { completeTransaction(); } beginTransaction(); try { // CMR collections should still be readable assertFalse(games.isEmpty()); assertEquals(2, games.size()); for (final Iterator iter = games.iterator(); iter.hasNext(); ) { final GameLocal game = (GameLocal) iter.next(); if (game.getId().equals(new Integer(11))) { assertEquals("value11", game.getName()); } else if (game.getId().equals(new Integer(22))) { assertEquals("value22", game.getName()); } else { fail(); } } // But CMR collections should not be modifiable try { games.add(newGame); fail("expected games.add(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.addAll(Arrays.asList(newGame)); fail("expected games.addAll(Arrays.asList(game)) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.remove(newGame); fail("expected games.remove(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } try { games.removeAll(Arrays.asList(newGame)); fail("expected games.removeAll(game) to throw an IllegalStateException"); } catch (final IllegalStateException expected) { } final Iterator iterator = games.iterator(); try { iterator.remove(); fail("expected iterator.remove() to throw an ConcurrentModificationException"); } catch (final ConcurrentModificationException expected) { } } finally { completeTransaction(); } } public void testIteratorConcurrentModification() throws Exception { resetDB(); beginTransaction(); final Set games; try { final PlatformLocal platform = findPlatform(new Integer(1)); final GameLocal game = findGame(new Integer(11)); games = platform.getGames(); assertFalse(games.isEmpty()); assertEquals(2, games.size()); final Iterator iterator = games.iterator(); games.remove(game); assertEquals(1, games.size()); try { iterator.next(); fail("expected iterator.next() to throw an ConcurrentModificationException"); } catch (final ConcurrentModificationException expected) { } } finally { completeTransaction(); } } public void testIteratorAndRemove() throws Exception { resetDB(); beginTransaction(); final Set games; try { final PlatformLocal platform = findPlatform(new Integer(1)); final GameLocal game = findGame(new Integer(11)); games = platform.getGames(); assertFalse(games.isEmpty()); assertEquals(2, games.size()); final Iterator iterator = games.iterator(); assertTrue(games.contains(game)); platform.remove(); assertFalse(games.contains(game)); assertEquals(0, games.size()); try { iterator.next(); fail("expected iterator.next() to throw an ConcurrentModificationException"); } catch (final ConcurrentModificationException expected) { } } finally { completeTransaction(); } } private void assertPlatformDeleted(final int platformId) throws Exception { final Connection c = ds.getConnection(); final Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM ComplexGame_ComplexPlatform WHERE Platforms_id=" + platformId); assertTrue(rs.next()); assertEquals(0, rs.getInt(1)); rs.close(); rs = s.executeQuery("SELECT COUNT(*) FROM ComplexPlatform WHERE id=" + platformId); assertTrue(rs.next()); assertEquals(0, rs.getInt(1)); rs.close(); s.close(); c.close(); } private void assertAllUnlinked() throws Exception { final Connection c = ds.getConnection(); final Statement s = c.createStatement(); final ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM ComplexGame_ComplexPlatform"); assertTrue(rs.next()); assertEquals(0, rs.getInt(1)); rs.close(); s.close(); c.close(); } private void assertLinked(final int platformId, final int gameId) throws Exception { final Connection c = ds.getConnection(); final Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT COUNT(*) FROM ComplexGame_ComplexPlatform WHERE Platforms_id = " + platformId + " AND Games_id = " + gameId); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); rs.close(); rs = s.executeQuery("SELECT name FROM ComplexPlatform WHERE id = " + platformId); assertTrue(rs.next()); assertEquals("value" + platformId, rs.getString(1)); rs = s.executeQuery("SELECT name FROM ComplexGame WHERE id = " + gameId); assertTrue(rs.next()); assertEquals("value" + gameId, rs.getString(1)); rs.close(); s.close(); c.close(); } private GameLocal createGame(final int gameId) throws CreateException { final GameLocal menu = gameLocalHome.create(new GamePk(gameId, "value" + gameId)); return menu; } private GameLocal findGame(final int gameId) throws FinderException { return gameLocalHome.findByPrimaryKey(new GamePk(gameId, "value" + gameId)); } private PlatformLocal createPlatform(final int platformId) throws CreateException { final PlatformLocal platform = platformLocalHome.create(new PlatformPk(platformId, "value" + platformId)); return platform; } private PlatformLocal findPlatform(final int platformId) throws FinderException { return platformLocalHome.findByPrimaryKey(new PlatformPk(platformId, "value" + platformId)); } private void resetDB() throws Exception { final Connection connection = ds.getConnection(); Statement statement = null; try { statement = connection.createStatement(); try { statement.execute("DELETE FROM ComplexGame_ComplexPlatform"); } catch (final SQLException ignored) { } try { statement.execute("DELETE FROM ComplexGame"); } catch (final SQLException ignored) { } try { statement.execute("DELETE FROM ComplexPlatform"); } catch (final SQLException ignored) { } } finally { close(statement); close(connection); } beginTransaction(); try { final PlatformLocal platform1 = createPlatform(1); assertNotNull("platform1.getGames() is null", platform1.getGames()); final PlatformLocal platform2 = createPlatform(2); assertNotNull("platform2.getGames() is null", platform2.getGames()); final PlatformLocal platform3 = createPlatform(3); assertNotNull("platform3.getGames() is null", platform3.getGames()); final GameLocal game1 = createGame(11); assertNotNull("game1.getPlatforms() is null", game1.getPlatforms()); final GameLocal game2 = createGame(22); assertNotNull("game2.getPlatforms() is null", game2.getPlatforms()); platform1.getGames().add(game1); platform1.getGames().add(game2); platform2.getGames().add(game2); platform3.getGames().add(game2); } finally { completeTransaction(); } } protected void dump() throws SQLException { dumpTable(ds, "ComplexGame"); dumpTable(ds, "ComplexPlatform"); dumpTable(ds, "ComplexGame_ComplexPlatform"); } }