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.geronimo.transaction.jpa;
017:
018: import java.util.Map;
019: import java.util.HashMap;
020:
021: import javax.persistence.EntityManager;
022: import javax.persistence.TransactionRequiredException;
023: import javax.ejb.EJBException;
024:
025: import junit.framework.TestCase;
026: import org.apache.geronimo.transaction.jta11.GeronimoTransactionManagerJTA11;
027: import org.apache.geronimo.transaction.mockjpa.MockEntityManagerFactory;
028: import org.apache.geronimo.transaction.mockjpa.MockEntityManager;
029:
030: /**
031: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
032: */
033: public class CMPEntityManagerTest extends TestCase {
034:
035: private GeronimoTransactionManagerJTA11 tm;
036: private String persistenceUnit = "foo";
037: private MockEntityManagerFactory entityManagerFactory;
038:
039: protected void setUp() throws Exception {
040: tm = new GeronimoTransactionManagerJTA11();
041: tm.addTransactionAssociationListener(new TransactionListener());
042: entityManagerFactory = new MockEntityManagerFactory();
043: }
044:
045: /**
046: * section 3.1.1
047: * (not very clear). getTransaction, joinTransaction throw IllegalStateException
048: */
049: public void testGetTransaction() throws Exception {
050: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
051: tm, persistenceUnit, entityManagerFactory, null);
052: try {
053: entityManager1.getTransaction();
054: fail("Expected IllegalStateException");
055: } catch (IllegalStateException e) {
056: //expected
057: } catch (Exception e) {
058: fail("Wrong exception " + e);
059: }
060: tm.begin();
061: try {
062: entityManager1.getTransaction();
063: fail("Expected IllegalStateException");
064: } catch (IllegalStateException e) {
065: //expected
066: } catch (Exception e) {
067: fail("Wrong exception " + e);
068: }
069: tm.commit();
070: }
071:
072: public void testJoinTransaction() throws Exception {
073: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
074: tm, persistenceUnit, entityManagerFactory, null);
075: try {
076: entityManager1.joinTransaction();
077: fail("Expected IllegalStateException");
078: } catch (IllegalStateException e) {
079: //expected
080: } catch (Exception e) {
081: fail("Wrong exception " + e);
082: }
083: tm.begin();
084: try {
085: entityManager1.joinTransaction();
086: fail("Expected IllegalStateException");
087: } catch (IllegalStateException e) {
088: //expected
089: } catch (Exception e) {
090: fail("Wrong exception " + e);
091: }
092: tm.commit();
093: }
094:
095: /**
096: * section 3.1.1 ????
097: * isOpen returns true
098: */
099: public void testIsOpen() throws Exception {
100: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
101: tm, persistenceUnit, entityManagerFactory, null);
102: assertTrue(entityManager1.isOpen());
103: tm.begin();
104: assertTrue(entityManager1.isOpen());
105: tm.commit();
106: assertTrue(entityManager1.isOpen());
107: tm.begin();
108: assertTrue(entityManager1.isOpen());
109: tm.rollback();
110: assertTrue(entityManager1.isOpen());
111: }
112:
113: /**
114: * section 5.6.2
115: * extended context is closed when the SFSB that caused it is removed
116: */
117: public void testExtendedClosedOnBeanRemove() throws Exception {
118: CMPEntityManagerExtended entityManager1 = new CMPEntityManagerExtended(
119: tm, persistenceUnit, entityManagerFactory, null);
120: MockEntityManager pc1 = (MockEntityManager) entityManager1
121: .find(EntityManager.class, "this");
122: assertTrue("base EntityManager should not be closed", !pc1
123: .isClosed());
124: assertNotNull("InternalEntityManager should be registered",
125: EntityManagerExtendedRegistry
126: .getEntityManager(persistenceUnit));
127: entityManager1.beanRemoved();
128: assertTrue("base EntityManager should be closed", pc1
129: .isClosed());
130: assertNull("InternalEntityManager should not be registered",
131: EntityManagerExtendedRegistry
132: .getEntityManager(persistenceUnit));
133: }
134:
135: /**
136: * section 5.6.2.1
137: * extended context is closed when the SFSB that caused it and all others that share it are removed
138: */
139: public void testInheritedExtendedClosedOnBeanRemove()
140: throws Exception {
141: CMPEntityManagerExtended entityManager1 = new CMPEntityManagerExtended(
142: tm, persistenceUnit, entityManagerFactory, null);
143: MockEntityManager pc1 = (MockEntityManager) entityManager1
144: .find(EntityManager.class, "this");
145: assertTrue("base EntityManager should not be closed", !pc1
146: .isClosed());
147: InternalCMPEntityManagerExtended internalEntityManager1 = EntityManagerExtendedRegistry
148: .getEntityManager(persistenceUnit);
149: assertNotNull("InternalEntityManager should be registered",
150: internalEntityManager1);
151: CMPEntityManagerExtended entityManager2 = new CMPEntityManagerExtended(
152: tm, persistenceUnit, entityManagerFactory, null);
153: InternalCMPEntityManagerExtended internalEntityManager2 = EntityManagerExtendedRegistry
154: .getEntityManager(persistenceUnit);
155: //we should have got an exception if this isn't true
156: assertSame(
157: "2nd entity manager registering should use same internal entity manager",
158: internalEntityManager1, internalEntityManager2);
159: MockEntityManager pc2 = (MockEntityManager) entityManager2
160: .find(EntityManager.class, "this");
161: assertSame(
162: "2nd entity manager registering should use same mock entity manager",
163: pc1, pc2);
164:
165: //remove one bean, internal and mock entity managers should not change state
166: entityManager1.beanRemoved();
167: assertTrue("base EntityManager should not be closed", !pc1
168: .isClosed());
169: assertNotNull("InternalEntityManager should be registered",
170: EntityManagerExtendedRegistry
171: .getEntityManager(persistenceUnit));
172:
173: //close other bean, everything should close and unregister
174: entityManager2.beanRemoved();
175: assertTrue("base EntityManager should be closed", pc1
176: .isClosed());
177: assertNull("InternalEntityManager should not be registered",
178: EntityManagerExtendedRegistry
179: .getEntityManager(persistenceUnit));
180: }
181:
182: /**
183: * section 5.6.3.1
184: * Trying to propagate a JTA tx with a persistence context bound into a SFSB with Extended persistence context
185: * results in an EJBException
186: */
187: public void testNoSimultaneousEntityManagers() throws Exception {
188: //set up the extended persistence context:
189: CMPEntityManagerExtended entityManager1 = new CMPEntityManagerExtended(
190: tm, persistenceUnit, entityManagerFactory, null);
191: //set up the caller
192: CMPEntityManagerTxScoped entityManager2 = new CMPEntityManagerTxScoped(
193: tm, persistenceUnit, entityManagerFactory, null);
194: tm.begin();
195: //register the caller
196: MockEntityManager pc1 = (MockEntityManager) entityManager2
197: .find(EntityManager.class, "this");
198: //caller calling SFSB means entityManager1 tries to join the trasaction:
199: InternalCMPEntityManagerExtended internalEntityManager = EntityManagerExtendedRegistry
200: .getEntityManager(persistenceUnit);
201: try {
202: internalEntityManager.joinTransaction();
203: fail("Expected EJBException");
204: } catch (EJBException e) {
205: //expected
206: } catch (Exception e) {
207: fail("Unexpected exception " + e);
208: }
209: tm.commit();
210: }
211:
212: /**
213: * section 5.8.2
214: * use the same persistence context for all work in a tx
215: */
216: public void testSamePersistenceContext() throws Exception {
217: tm.begin();
218: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
219: tm, persistenceUnit, entityManagerFactory, null);
220: EntityManager pc1 = entityManager1.find(EntityManager.class,
221: "this");
222: CMPEntityManagerTxScoped entityManager2 = new CMPEntityManagerTxScoped(
223: tm, persistenceUnit, entityManagerFactory, null);
224: EntityManager pc2 = entityManager2.find(EntityManager.class,
225: "this");
226: assertSame(
227: "Should get same entity manager for all work in a tx",
228: pc1, pc2);
229: tm.commit();
230: }
231:
232: /**
233: * section 5.9.1
234: * close or cleared is called when tx commits
235: */
236: public void testCloseOnCommit() throws Exception {
237: tm.begin();
238: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
239: tm, persistenceUnit, entityManagerFactory, null);
240: MockEntityManager pc1 = (MockEntityManager) entityManager1
241: .find(EntityManager.class, "this");
242: assertTrue("entityManager should not be closed or cleared",
243: !pc1.isClosed() & !pc1.isCleared());
244: tm.commit();
245: assertTrue("entityManager should be closed or cleared", pc1
246: .isClosed()
247: || pc1.isCleared());
248: tm.begin();
249: CMPEntityManagerTxScoped entityManager2 = new CMPEntityManagerTxScoped(
250: tm, persistenceUnit, entityManagerFactory, null);
251: MockEntityManager pc2 = (MockEntityManager) entityManager2
252: .find(EntityManager.class, "this");
253: assertTrue("entityManager should not be closed or cleared",
254: !pc2.isClosed() & !pc2.isCleared());
255: tm.rollback();
256: assertTrue("entityManager should be closed or cleared", pc2
257: .isClosed()
258: || pc2.isCleared());
259: }
260:
261: /**
262: * section 5.9.1
263: * transaction required for persist, remove, merge, refresh
264: */
265: public void testTransactionRequired() throws Exception {
266: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
267: tm, persistenceUnit, entityManagerFactory, null);
268: try {
269: entityManager1.persist("foo");
270: fail("expected TransactionRequiredException");
271: } catch (TransactionRequiredException e) {
272: //expected
273: } catch (Exception e) {
274: fail("Wrong exception" + e);
275: }
276: try {
277: entityManager1.remove("foo");
278: fail("expected TransactionRequiredException");
279: } catch (TransactionRequiredException e) {
280: //expected
281: } catch (Exception e) {
282: fail("Wrong exception" + e);
283: }
284: try {
285: entityManager1.merge("foo");
286: fail("expected TransactionRequiredException");
287: } catch (TransactionRequiredException e) {
288: //expected
289: } catch (Exception e) {
290: fail("Wrong exception" + e);
291: }
292: try {
293: entityManager1.refresh("foo");
294: fail("expected TransactionRequiredException");
295: } catch (TransactionRequiredException e) {
296: //expected
297: } catch (Exception e) {
298: fail("Wrong exception" + e);
299: }
300: }
301:
302: /**
303: * section 5.9.1
304: * when a SFSB/extended context starts a UserTransaction or a CMT tx starts the EM must join the transaction
305: */
306: public void testExtendedEntityManagerJoinsNewTransactions()
307: throws Exception {
308: CMPEntityManagerExtended entityManager1 = new CMPEntityManagerExtended(
309: tm, persistenceUnit, entityManagerFactory, null);
310: tm.begin();
311: MockEntityManager pc1 = (MockEntityManager) entityManager1
312: .find(EntityManager.class, "this");
313:
314: assertTrue("EntityManager was supposed to join the tx", pc1
315: .isJoined());
316: }
317:
318: /**
319: * section 5.9.1
320: * application must not call close on its entityManager
321: */
322: public void testAppCallsCloseForbidden() throws Exception {
323: CMPEntityManagerTxScoped entityManager1 = new CMPEntityManagerTxScoped(
324: tm, persistenceUnit, entityManagerFactory, null);
325: try {
326: entityManager1.close();
327: fail("Application should not be able to call close on its EntityManager");
328: } catch (IllegalStateException e) {
329: //expected
330: }
331: tm.begin();
332: try {
333: entityManager1.close();
334: fail("Application should not be able to call close on its EntityManager");
335: } catch (IllegalStateException e) {
336: //expected
337: }
338: tm.commit();
339: }
340:
341: /**
342: * section 5.9.1
343: *
344: * @throws Exception
345: */
346: public void testNoPropertiesUsed() throws Exception {
347:
348: CMPEntityManagerTxScoped entityManager = new CMPEntityManagerTxScoped(
349: tm, persistenceUnit, entityManagerFactory, null);
350: tm.begin();
351: entityManager.contains("bar");
352: Map props = entityManager.find(Map.class, "properties");
353: assertSame("Props are not null", props, null);
354: tm.commit();
355: }
356:
357: /**
358: * section 5.9.1
359: *
360: * @throws Exception
361: */
362: public void testPropertiesUsed() throws Exception {
363: Map properties = new HashMap();
364: CMPEntityManagerTxScoped entityManager = new CMPEntityManagerTxScoped(
365: tm, persistenceUnit, entityManagerFactory, properties);
366: tm.begin();
367: entityManager.contains("bar");
368: Map props = entityManager.find(Map.class, "properties");
369: assertSame("Props are not what was passed in", props,
370: properties);
371: tm.commit();
372: }
373: }
|