001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.persistence.callbacks;
020:
021: import java.util.Set;
022: import java.util.HashSet;
023: import javax.persistence.EntityManager;
024: import javax.persistence.RollbackException;
025:
026: import org.apache.openjpa.persistence.OpenJPAPersistence;
027: import org.apache.openjpa.persistence.callbacks.ExceptionsFromCallbacksEntity.CallbackTestException;
028: import org.apache.openjpa.persistence.test.SingleEMFTestCase;
029: import org.apache.openjpa.enhance.PersistenceCapable;
030:
031: /**
032: * Tests against JPA section 3.5's description of callback exception handling.
033: */
034: public class TestExceptionsFromCallbacks extends SingleEMFTestCase {
035:
036: public static boolean testRunning = false;
037:
038: @Override
039: public void setUp() {
040: Set needEnhancement = new HashSet();
041: needEnhancement
042: .add("testPostUpdateExceptionDuringFlushWithNewInstance");
043: needEnhancement
044: .add("testPreUpdateExceptionDuringFlushWithExistingFlushedInstance");
045: needEnhancement
046: .add("testPreUpdateExceptionDuringCommitWithExistingFlushedInstance");
047: needEnhancement
048: .add("testPostUpdateExceptionDuringFlushWithExistingFlushedInstance");
049: needEnhancement
050: .add("testPostUpdateExceptionDuringCommitWithExistingFlushedInstance");
051: if (!PersistenceCapable.class
052: .isAssignableFrom(ExceptionsFromCallbacksEntity.class)
053: && needEnhancement.contains(getName()))
054: // actually, we really only need redef
055: fail("this test method does not work without enhancement");
056:
057: setUp(ExceptionsFromCallbacksEntity.class, CLEAR_TABLES,
058: "openjpa.Log", "SQL=TRACE");
059: testRunning = true;
060: }
061:
062: @Override
063: public void tearDown() throws Exception {
064: testRunning = false;
065: super .tearDown();
066: }
067:
068: public void testPrePersistException() {
069: EntityManager em = emf.createEntityManager();
070: em.getTransaction().begin();
071: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
072: o.setThrowOnPrePersist(true);
073: try {
074: em.persist(o);
075: fail("persist should have failed");
076: } catch (CallbackTestException cte) {
077: // transaction should be still active, but marked for rollback
078: assertTrue(em.getTransaction().isActive());
079: assertTrue(em.getTransaction().getRollbackOnly());
080: } finally {
081: if (em.getTransaction().isActive())
082: em.getTransaction().rollback();
083: em.close();
084: }
085: }
086:
087: public void testPrePersistExceptionOnMerge() {
088: EntityManager em = emf.createEntityManager();
089: em.getTransaction().begin();
090: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
091: o.setThrowOnPrePersist(true);
092: try {
093: em.merge(o);
094: fail("merge should have failed");
095: } catch (CallbackTestException cte) {
096: // transaction should be still active, but marked for rollback
097: assertTrue(em.getTransaction().isActive());
098: assertTrue(em.getTransaction().getRollbackOnly());
099: } finally {
100: if (em.getTransaction().isActive())
101: em.getTransaction().rollback();
102: em.close();
103: }
104: }
105:
106: public void testPostPersistExceptionDuringFlush() {
107: EntityManager em = emf.createEntityManager();
108: em.getTransaction().begin();
109: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
110: o.setThrowOnPostPersist(true);
111: em.persist(o);
112: mutateAndFlush(em, o);
113: }
114:
115: private void mutateAndFlush(EntityManager em,
116: ExceptionsFromCallbacksEntity o) {
117: o.setStringField("foo");
118: flush(em);
119: }
120:
121: private void flush(EntityManager em) {
122: try {
123: em.flush();
124: fail("flush should have failed");
125: } catch (CallbackTestException cte) {
126: // transaction should be still active, but marked for rollback
127: assertTrue(em.getTransaction().isActive());
128: assertTrue(em.getTransaction().getRollbackOnly());
129: } finally {
130: if (em.getTransaction().isActive())
131: em.getTransaction().rollback();
132: em.close();
133: }
134: }
135:
136: public void testPostPersistExceptionDuringCommit() {
137: EntityManager em = emf.createEntityManager();
138: em.getTransaction().begin();
139: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
140: o.setThrowOnPostPersist(true);
141: em.persist(o);
142: mutateAndCommit(em, o);
143: }
144:
145: private void mutateAndCommit(EntityManager em,
146: ExceptionsFromCallbacksEntity o) {
147: o.setStringField("foo");
148: commit(em);
149: }
150:
151: private void commit(EntityManager em) {
152: try {
153: em.getTransaction().commit();
154: fail("commit should have failed");
155: } catch (RollbackException re) {
156: assertEquals(CallbackTestException.class, re.getCause()
157: .getClass());
158:
159: // transaction should be rolled back at this point
160: assertFalse(em.getTransaction().isActive());
161: } finally {
162: if (em.getTransaction().isActive())
163: em.getTransaction().rollback();
164: em.close();
165: }
166: }
167:
168: public void testPrePersistExceptionDuringFlushWithNewFlushedInstance() {
169: EntityManager em = emf.createEntityManager();
170: em.getTransaction().begin();
171: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
172: em.persist(o);
173: em.flush();
174: o.setThrowOnPrePersist(true);
175: // should pass; pre-persist should not be triggered
176: o.setStringField("foo");
177: em.flush();
178: em.getTransaction().commit();
179: em.close();
180: }
181:
182: public void testPrePersistExceptionDuringCommitWithNewFlushedInstance() {
183: EntityManager em = emf.createEntityManager();
184: em.getTransaction().begin();
185: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
186: em.persist(o);
187: em.flush();
188: o.setThrowOnPrePersist(true);
189: // should pass; pre-persist should not be triggered
190: o.setStringField("foo");
191: em.getTransaction().commit();
192: em.close();
193: }
194:
195: public void testPostPersistExceptionDuringFlushWithNewFlushedInstance() {
196: EntityManager em = emf.createEntityManager();
197: em.getTransaction().begin();
198: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
199: em.persist(o);
200: em.flush();
201: o.setThrowOnPostPersist(true);
202: // should pass; post-persist should not be triggered
203: o.setStringField("foo");
204: em.flush();
205: em.getTransaction().commit();
206: em.close();
207: }
208:
209: public void testPostPersistExceptionDuringCommitWithNewFlushedInstance() {
210: EntityManager em = emf.createEntityManager();
211: em.getTransaction().begin();
212: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
213: em.persist(o);
214: em.flush();
215: o.setThrowOnPostPersist(true);
216: // should pass; post-persist should not be triggered
217: o.setStringField("foo");
218: em.getTransaction().commit();
219: em.close();
220: }
221:
222: public void testPreUpdateExceptionWithNewInstance() {
223: EntityManager em = emf.createEntityManager();
224: em.getTransaction().begin();
225: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
226: o.setThrowOnPreUpdate(true);
227: em.persist(o);
228: o.setStringField("foo");
229: em.getTransaction().commit();
230: em.close();
231: }
232:
233: public void testPostUpdateExceptionDuringFlushWithNewInstance() {
234: EntityManager em = emf.createEntityManager();
235: em.getTransaction().begin();
236: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
237: o.setThrowOnPostUpdate(true);
238: em.persist(o);
239: o.setStringField("foo");
240: em.flush();
241: em.getTransaction().commit();
242: em.close();
243: }
244:
245: public void testPostUpdateExceptionDuringCommitWithNewInstance() {
246: EntityManager em = emf.createEntityManager();
247: em.getTransaction().begin();
248: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
249: o.setThrowOnPostUpdate(true);
250: em.persist(o);
251: o.setStringField("foo");
252: em.getTransaction().commit();
253: em.close();
254: }
255:
256: public void testPreUpdateExceptionDuringFlushWithNewFlushedInstance() {
257: EntityManager em = emf.createEntityManager();
258: em.getTransaction().begin();
259: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
260: em.persist(o);
261: em.flush();
262: o.setThrowOnPreUpdate(true);
263: mutateAndFlush(em, o);
264: }
265:
266: public void testPreUpdateExceptionDuringCommitWithNewFlushedInstance() {
267: EntityManager em = emf.createEntityManager();
268: em.getTransaction().begin();
269: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
270: em.persist(o);
271: em.flush();
272: o.setThrowOnPreUpdate(true);
273: mutateAndCommit(em, o);
274: }
275:
276: public void testPostUpdateExceptionDuringFlushWithNewFlushedInstance() {
277: EntityManager em = emf.createEntityManager();
278: em.getTransaction().begin();
279: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
280: em.persist(o);
281: em.flush();
282: o.setThrowOnPostUpdate(true);
283: mutateAndFlush(em, o);
284: }
285:
286: public void testPostUpdateExceptionDuringCommitWithNewFlushedInstance() {
287: EntityManager em = emf.createEntityManager();
288: em.getTransaction().begin();
289: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
290: em.persist(o);
291: em.flush();
292: o.setThrowOnPostUpdate(true);
293: mutateAndCommit(em, o);
294: }
295:
296: public void testPreUpdateExceptionDuringFlushWithExistingInstance() {
297: Object oid = insert("new instance");
298:
299: EntityManager em = emf.createEntityManager();
300: em.getTransaction().begin();
301: ExceptionsFromCallbacksEntity o = em.find(
302: ExceptionsFromCallbacksEntity.class, oid);
303: o.setThrowOnPreUpdate(true);
304: mutateAndFlush(em, o);
305: }
306:
307: private Object insert(String s) {
308: EntityManager em = emf.createEntityManager();
309: em.getTransaction().begin();
310: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
311: o.setStringField(s);
312: em.persist(o);
313: em.getTransaction().commit();
314: em.close();
315: return o.getId();
316: }
317:
318: public void testPreUpdateExceptionDuringCommitWithExistingInstance() {
319: Object oid = insert("new instance");
320:
321: EntityManager em = emf.createEntityManager();
322: em.getTransaction().begin();
323: ExceptionsFromCallbacksEntity o = em.find(
324: ExceptionsFromCallbacksEntity.class, oid);
325: o.setThrowOnPreUpdate(true);
326: mutateAndCommit(em, o);
327: }
328:
329: public void testPostUpdateExceptionDuringFlushWithExistingInstance() {
330: Object oid = insert("new instance");
331:
332: EntityManager em = emf.createEntityManager();
333: em.getTransaction().begin();
334: ExceptionsFromCallbacksEntity o = em.find(
335: ExceptionsFromCallbacksEntity.class, oid);
336: o.setThrowOnPostUpdate(true);
337: mutateAndFlush(em, o);
338: }
339:
340: public void testPostUpdateExceptionDuringCommitWithExistingInstance() {
341: Object oid = insert("new instance");
342:
343: EntityManager em = emf.createEntityManager();
344: em.getTransaction().begin();
345: ExceptionsFromCallbacksEntity o = em.find(
346: ExceptionsFromCallbacksEntity.class, oid);
347: o.setThrowOnPostUpdate(true);
348: mutateAndCommit(em, o);
349: }
350:
351: public void testPreUpdateExceptionDuringFlushWithExistingFlushedInstance() {
352: Object oid = insert("new instance");
353:
354: EntityManager em = emf.createEntityManager();
355: em.getTransaction().begin();
356: ExceptionsFromCallbacksEntity o = em.find(
357: ExceptionsFromCallbacksEntity.class, oid);
358: o.setStringField("foo");
359: em.flush();
360: o.setThrowOnPreUpdate(true);
361: // there's no additional flush work; should not re-invoke the callback
362: em.flush();
363: em.getTransaction().commit();
364: em.close();
365: }
366:
367: public void testPreUpdateExceptionDuringCommitWithExistingFlushedInstance() {
368: Object oid = insert("new instance");
369:
370: EntityManager em = emf.createEntityManager();
371: em.getTransaction().begin();
372: ExceptionsFromCallbacksEntity o = em.find(
373: ExceptionsFromCallbacksEntity.class, oid);
374: o.setStringField("foo");
375: em.flush();
376: o.setThrowOnPreUpdate(true);
377: // there's no additional flush work; should not re-invoke the callback
378: em.getTransaction().commit();
379: em.close();
380: }
381:
382: public void testPostUpdateExceptionDuringFlushWithExistingFlushedInstance() {
383: Object oid = insert("new instance");
384:
385: EntityManager em = emf.createEntityManager();
386: em.getTransaction().begin();
387: ExceptionsFromCallbacksEntity o = em.find(
388: ExceptionsFromCallbacksEntity.class, oid);
389: o.setStringField("foo");
390: em.flush();
391: o.setThrowOnPostUpdate(true);
392: // no mutations; should not trigger a PostUpdate
393: em.flush();
394: em.getTransaction().commit();
395: em.close();
396: }
397:
398: public void testPostUpdateExceptionDuringCommitWithExistingFlushedInstance() {
399: Object oid = insert("new instance");
400:
401: EntityManager em = emf.createEntityManager();
402: em.getTransaction().begin();
403: ExceptionsFromCallbacksEntity o = em.find(
404: ExceptionsFromCallbacksEntity.class, oid);
405: o.setStringField("foo");
406: em.flush();
407: // no mutations; should not trigger a PostUpdate
408: o.setThrowOnPostUpdate(true);
409: em.getTransaction().commit();
410: em.close();
411: }
412:
413: public void testPostLoadException() {
414: EntityManager em = emf.createEntityManager();
415: em.getTransaction().begin();
416: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
417: o.setThrowOnPostLoad(true);
418: em.persist(o);
419: em.getTransaction().commit();
420: Object oid = OpenJPAPersistence.cast(em).getObjectId(o);
421: em.close();
422:
423: em = emf.createEntityManager();
424: em.getTransaction().begin();
425: try {
426: em.find(ExceptionsFromCallbacksEntity.class, oid);
427: fail("find should have failed");
428: } catch (CallbackTestException cte) {
429: // transaction should be active but marked for rollback
430: assertTrue(em.getTransaction().isActive());
431: assertTrue(em.getTransaction().getRollbackOnly());
432: } finally {
433: if (em.getTransaction().isActive())
434: em.getTransaction().rollback();
435: em.close();
436: }
437: }
438:
439: public void testPreDeleteException() {
440: EntityManager em = emf.createEntityManager();
441: em.getTransaction().begin();
442: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
443: em.persist(o);
444: em.flush();
445: o.setThrowOnPreRemove(true);
446: try {
447: em.remove(o);
448: } catch (CallbackTestException cte) {
449: // transaction should be active but marked for rollback
450: assertTrue(em.getTransaction().isActive());
451: assertTrue(em.getTransaction().getRollbackOnly());
452: } finally {
453: if (em.getTransaction().isActive())
454: em.getTransaction().rollback();
455: em.close();
456: }
457: }
458:
459: public void testPostDeleteExceptionDuringFlush() {
460: EntityManager em = emf.createEntityManager();
461: em.getTransaction().begin();
462: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
463: em.persist(o);
464: em.flush();
465: o.setThrowOnPostRemove(true);
466: try {
467: em.remove(o);
468: } catch (CallbackTestException e) {
469: em.getTransaction().rollback();
470: em.close();
471: fail("PostRemove is being called too soon (before SQL is issued)");
472: }
473: flush(em);
474: }
475:
476: public void testPostDeleteExceptionDuringCommit() {
477: EntityManager em = emf.createEntityManager();
478: em.getTransaction().begin();
479: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
480: em.persist(o);
481: em.flush();
482: o.setThrowOnPostRemove(true);
483: try {
484: em.remove(o);
485: } catch (CallbackTestException e) {
486: em.getTransaction().rollback();
487: em.close();
488: fail("PostRemove is being called too soon (before SQL is issued)");
489: }
490: commit(em);
491: }
492:
493: public void testPreDeleteExceptionDoubleDelete() {
494: EntityManager em = emf.createEntityManager();
495: em.getTransaction().begin();
496: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
497: em.persist(o);
498: em.flush();
499: // this should pass
500: em.remove(o);
501: em.flush();
502: o.setThrowOnPreRemove(true);
503: // this shoud also pass; no work to do for delete
504: em.remove(o);
505: em.getTransaction().commit();
506: em.close();
507: }
508:
509: public void testPostDeleteExceptionDuringFlushDoubleDelete() {
510: EntityManager em = emf.createEntityManager();
511: em.getTransaction().begin();
512: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
513: em.persist(o);
514: em.flush();
515: // this should pass
516: em.remove(o);
517: em.flush();
518: o.setThrowOnPostRemove(true);
519: // this shoud also pass; no work to do for delete
520: em.remove(o);
521: em.flush();
522: em.getTransaction().commit();
523: em.close();
524: }
525:
526: public void testPostDeleteExceptionDuringCommitDoubleDelete() {
527: EntityManager em = emf.createEntityManager();
528: em.getTransaction().begin();
529: ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
530: em.persist(o);
531: em.flush();
532: // this should pass
533: em.remove(o);
534: em.flush();
535: o.setThrowOnPostRemove(true);
536: // this shoud also pass; no work to do for delete
537: em.remove(o);
538: em.getTransaction().commit();
539: em.close();
540: }
541: }
|