1 /* 2 * Copyright (C) 2010 Google, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.persist.jpa; 18 19 import com.google.inject.Guice; 20 import com.google.inject.Inject; 21 import com.google.inject.Injector; 22 import com.google.inject.persist.PersistService; 23 import com.google.inject.persist.Transactional; 24 import java.io.FileNotFoundException; 25 import java.io.IOException; 26 import java.util.Date; 27 import java.util.List; 28 import javax.persistence.EntityManager; 29 import junit.framework.TestCase; 30 31 /** 32 * This test asserts class level @Transactional annotation behavior. 33 * 34 * <p>Class-level @Transactional is a shortcut if all non-private methods in the class are meant to 35 * be transactional. 36 * 37 * @author Dhanji R. Prasanna (dhanji@gmail.com) 38 */ 39 40 public class ClassLevelManagedLocalTransactionsTest extends TestCase { 41 private Injector injector; 42 private static final String UNIQUE_TEXT = "JPAsome unique text88888" + new Date(); 43 private static final String UNIQUE_TEXT_2 = "JPAsome asda unique teasdalsdplasdxt" + new Date(); 44 private static final String TRANSIENT_UNIQUE_TEXT = 45 "JPAsome other unique texaksoksojadasdt" + new Date(); 46 47 @Override setUp()48 public void setUp() { 49 injector = Guice.createInjector(new JpaPersistModule("testUnit")); 50 51 //startup persistence 52 injector.getInstance(PersistService.class).start(); 53 } 54 55 @Override tearDown()56 public void tearDown() { 57 injector.getInstance(PersistService.class).stop(); 58 injector = null; 59 } 60 testSimpleTransaction()61 public void testSimpleTransaction() { 62 injector.getInstance(TransactionalObject.class).runOperationInTxn(); 63 64 EntityManager session = injector.getInstance(EntityManager.class); 65 assertFalse( 66 "EntityManager was not closed by transactional service", 67 session.getTransaction().isActive()); 68 69 //test that the data has been stored 70 session.getTransaction().begin(); 71 Object result = 72 session 73 .createQuery("from JpaTestEntity where text = :text") 74 .setParameter("text", UNIQUE_TEXT) 75 .getSingleResult(); 76 77 session.getTransaction().commit(); 78 79 assertTrue("odd result returned fatal", result instanceof JpaTestEntity); 80 81 assertEquals( 82 "queried entity did not match--did automatic txn fail?", 83 UNIQUE_TEXT, 84 (((JpaTestEntity) result).getText())); 85 } 86 testSimpleTransactionRollbackOnChecked()87 public void testSimpleTransactionRollbackOnChecked() { 88 try { 89 injector.getInstance(TransactionalObject2.class).runOperationInTxnThrowingChecked(); 90 } catch (IOException e) { 91 //ignore 92 } 93 94 EntityManager session = injector.getInstance(EntityManager.class); 95 assertFalse( 96 "EntityManager was not closed by transactional service (rollback didnt happen?)", 97 session.getTransaction().isActive()); 98 99 //test that the data has been stored 100 session.getTransaction().begin(); 101 List<?> result = 102 session 103 .createQuery("from JpaTestEntity where text = :text") 104 .setParameter("text", TRANSIENT_UNIQUE_TEXT) 105 .getResultList(); 106 107 session.getTransaction().commit(); 108 109 assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty()); 110 } 111 testSimpleTransactionRollbackOnCheckedExcepting()112 public void testSimpleTransactionRollbackOnCheckedExcepting() { 113 Exception ex = null; 114 try { 115 injector.getInstance(TransactionalObject3.class).runOperationInTxnThrowingCheckedExcepting(); 116 fail("Exception was not thrown by test txn-al method!"); 117 } catch (IOException e) { 118 //ignored 119 } 120 121 EntityManager session = injector.getInstance(EntityManager.class); 122 assertFalse( 123 "Txn was not closed by transactional service (commit didnt happen?)", 124 session.getTransaction().isActive()); 125 126 //test that the data has been stored 127 session.getTransaction().begin(); 128 Object result = 129 session 130 .createQuery("from JpaTestEntity where text = :text") 131 .setParameter("text", UNIQUE_TEXT_2) 132 .getSingleResult(); 133 134 session.getTransaction().commit(); 135 136 assertNotNull("a result was not returned! rollback happened anyway (ignore failed)!!!", result); 137 } 138 testSimpleTransactionRollbackOnUnchecked()139 public void testSimpleTransactionRollbackOnUnchecked() { 140 try { 141 injector.getInstance(TransactionalObject4.class).runOperationInTxnThrowingUnchecked(); 142 } catch (RuntimeException re) { 143 //ignore 144 } 145 146 EntityManager session = injector.getInstance(EntityManager.class); 147 assertFalse( 148 "EntityManager was not closed by transactional service (rollback didnt happen?)", 149 session.getTransaction().isActive()); 150 151 //test that the data has been stored 152 session.getTransaction().begin(); 153 List<?> result = 154 session 155 .createQuery("from JpaTestEntity where text = :text") 156 .setParameter("text", TRANSIENT_UNIQUE_TEXT) 157 .getResultList(); 158 159 session.getTransaction().commit(); 160 161 assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty()); 162 } 163 164 @Transactional 165 public static class TransactionalObject { 166 @Inject EntityManager session; 167 runOperationInTxn()168 public void runOperationInTxn() { 169 assertTrue(session.getTransaction().isActive()); 170 JpaTestEntity entity = new JpaTestEntity(); 171 entity.setText(UNIQUE_TEXT); 172 session.persist(entity); 173 } 174 } 175 176 @Transactional 177 public static class TransactionalObject4 { 178 @Inject EntityManager session; 179 180 @Transactional runOperationInTxnThrowingUnchecked()181 public void runOperationInTxnThrowingUnchecked() { 182 assertTrue(session.getTransaction().isActive()); 183 JpaTestEntity entity = new JpaTestEntity(); 184 entity.setText(TRANSIENT_UNIQUE_TEXT); 185 session.persist(entity); 186 187 throw new IllegalStateException(); 188 } 189 } 190 191 @Transactional(rollbackOn = IOException.class, ignore = FileNotFoundException.class) 192 public static class TransactionalObject3 { 193 @Inject EntityManager session; 194 runOperationInTxnThrowingCheckedExcepting()195 public void runOperationInTxnThrowingCheckedExcepting() throws IOException { 196 assertTrue(session.getTransaction().isActive()); 197 JpaTestEntity entity = new JpaTestEntity(); 198 entity.setText(UNIQUE_TEXT_2); 199 session.persist(entity); 200 201 throw new FileNotFoundException(); 202 } 203 } 204 205 @Transactional(rollbackOn = IOException.class) 206 public static class TransactionalObject2 { 207 @Inject EntityManager session; 208 runOperationInTxnThrowingChecked()209 public void runOperationInTxnThrowingChecked() throws IOException { 210 assertTrue(session.getTransaction().isActive()); 211 JpaTestEntity entity = new JpaTestEntity(); 212 entity.setText(TRANSIENT_UNIQUE_TEXT); 213 session.persist(entity); 214 215 throw new IOException(); 216 } 217 } 218 } 219