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.name.Named; 23 import com.google.inject.persist.PersistService; 24 import com.google.inject.persist.Transactional; 25 import com.google.inject.persist.UnitOfWork; 26 import com.google.inject.persist.finder.Finder; 27 28 import junit.framework.TestCase; 29 30 import java.io.IOException; 31 import java.util.Date; 32 33 import javax.persistence.EntityManager; 34 import javax.persistence.EntityManagerFactory; 35 import javax.persistence.NoResultException; 36 37 /** 38 * @author Dhanji R. Prasanna (dhanji@gmail.com) 39 */ 40 41 public class ManagedLocalTransactionsAcrossRequestTest extends TestCase { 42 private Injector injector; 43 private static final String UNIQUE_TEXT = "some unique text" + new Date(); 44 private static final String UNIQUE_TEXT_MERGE = "meRG_Esome unique text" + new Date(); 45 private static final String UNIQUE_TEXT_MERGE_FORDF = "aSdoaksdoaksdmeRG_Esome unique text" 46 + new Date(); 47 private static final String TRANSIENT_UNIQUE_TEXT = "some other unique text" + new Date(); 48 49 @Override setUp()50 public void setUp() { 51 injector = Guice.createInjector(new JpaPersistModule("testUnit")); 52 53 //startup persistence 54 injector.getInstance(PersistService.class).start(); 55 } 56 57 @Override tearDown()58 public final void tearDown() { 59 injector.getInstance(EntityManagerFactory.class).close(); 60 } 61 testSimpleTransaction()62 public void testSimpleTransaction() { 63 injector.getInstance(TransactionalObject.class).runOperationInTxn(); 64 65 EntityManager em = injector.getInstance(EntityManager.class); 66 assertFalse(em.getTransaction().isActive()); 67 68 //test that the data has been stored 69 Object result = em.createQuery("from JpaTestEntity where text = :text") 70 .setParameter("text", UNIQUE_TEXT).getSingleResult(); 71 injector.getInstance(UnitOfWork.class).end(); 72 73 assertTrue("odd result returned fatal", result instanceof JpaTestEntity); 74 75 assertEquals("queried entity did not match--did automatic txn fail?", 76 UNIQUE_TEXT, ((JpaTestEntity) result).getText()); 77 injector.getInstance(UnitOfWork.class).end(); 78 79 } 80 testSimpleTransactionWithMerge()81 public void testSimpleTransactionWithMerge() { 82 EntityManager emOrig = injector.getInstance(EntityManager.class); 83 JpaTestEntity entity = injector.getInstance(TransactionalObject.class) 84 .runOperationInTxnWithMerge(); 85 86 assertNotNull("Entity was not given an id (was not persisted correctly?)", entity.getId()); 87 88 EntityManager em = injector.getInstance(EntityManager.class); 89 assertFalse(em.getTransaction().isActive()); 90 91 //test that the data has been stored 92 assertTrue("Em was closed after txn!", em.isOpen()); 93 assertEquals("Em was not kept open across txns", emOrig, em); 94 assertTrue("Merge did not store state or did not return persistent copy", em.contains(entity)); 95 96 Object result = em.createQuery("from JpaTestEntity where text = :text") 97 .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult(); 98 injector.getInstance(UnitOfWork.class).end(); 99 100 assertTrue(result instanceof JpaTestEntity); 101 102 assertEquals("queried entity did not match--did automatic txn fail?", 103 UNIQUE_TEXT_MERGE, ((JpaTestEntity) result).getText()); 104 injector.getInstance(UnitOfWork.class).end(); 105 106 } 107 disabled_testSimpleTransactionWithMergeAndDF()108 public void disabled_testSimpleTransactionWithMergeAndDF() { 109 EntityManager emOrig = injector.getInstance(EntityManager.class); 110 JpaTestEntity entity = injector.getInstance(TransactionalObject.class) 111 .runOperationInTxnWithMergeForDf(); 112 113 EntityManager em = injector.getInstance(EntityManager.class); 114 assertFalse("txn was not closed by transactional service", em.getTransaction().isActive()); 115 116 //test that the data has been stored 117 assertTrue("Em was closed after txn!", em.isOpen()); 118 assertEquals("Em was not kept open across txns", emOrig, em); 119 assertTrue("Merge did not store state or did not return persistent copy", em.contains(entity)); 120 121 Object result = injector.getInstance(TransactionalObject.class).find(UNIQUE_TEXT_MERGE_FORDF); 122 injector.getInstance(UnitOfWork.class).end(); 123 124 assertNotNull(result); 125 assertTrue(result instanceof JpaTestEntity); 126 127 assertEquals("queried entity did not match--did automatic txn fail?", 128 UNIQUE_TEXT_MERGE_FORDF, ((JpaTestEntity) result).getText()); 129 injector.getInstance(UnitOfWork.class).end(); 130 131 } 132 testSimpleTransactionRollbackOnChecked()133 public void testSimpleTransactionRollbackOnChecked() { 134 try { 135 injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingChecked(); 136 } catch (IOException e) { 137 //ignore 138 injector.getInstance(UnitOfWork.class).end(); 139 } 140 141 EntityManager em = injector.getInstance(EntityManager.class); 142 143 assertFalse("Previous EM was not closed by transactional service (rollback didnt happen?)", 144 em.getTransaction().isActive()); 145 146 //test that the data has been stored 147 try { 148 Object result = em.createQuery("from JpaTestEntity where text = :text") 149 .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult(); 150 injector.getInstance(UnitOfWork.class).end(); 151 fail(); 152 } catch (NoResultException e) {} 153 154 injector.getInstance(UnitOfWork.class).end(); 155 } 156 testSimpleTransactionRollbackOnUnchecked()157 public void testSimpleTransactionRollbackOnUnchecked() { 158 try { 159 injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingUnchecked(); 160 } catch (RuntimeException re) { 161 //ignore 162 injector.getInstance(UnitOfWork.class).end(); 163 } 164 165 EntityManager em = injector.getInstance(EntityManager.class); 166 assertFalse("Session was not closed by transactional service (rollback didnt happen?)", 167 em.getTransaction().isActive()); 168 169 try { 170 Object result = em.createQuery("from JpaTestEntity where text = :text") 171 .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult(); 172 injector.getInstance(UnitOfWork.class).end(); 173 fail(); 174 } catch (NoResultException e) {} 175 176 injector.getInstance(UnitOfWork.class).end(); 177 } 178 179 public static class TransactionalObject { 180 private final EntityManager em; 181 182 @Inject TransactionalObject(EntityManager em)183 public TransactionalObject(EntityManager em) { 184 this.em = em; 185 } 186 187 @Transactional runOperationInTxn()188 public void runOperationInTxn() { 189 JpaTestEntity entity = new JpaTestEntity(); 190 entity.setText(UNIQUE_TEXT); 191 em.persist(entity); 192 } 193 194 @Transactional runOperationInTxnWithMerge()195 public JpaTestEntity runOperationInTxnWithMerge() { 196 JpaTestEntity entity = new JpaTestEntity(); 197 entity.setText(UNIQUE_TEXT_MERGE); 198 return em.merge(entity); 199 } 200 201 @Transactional runOperationInTxnWithMergeForDf()202 public JpaTestEntity runOperationInTxnWithMergeForDf() { 203 JpaTestEntity entity = new JpaTestEntity(); 204 entity.setText(UNIQUE_TEXT_MERGE_FORDF); 205 return em.merge(entity); 206 } 207 208 @Transactional(rollbackOn = IOException.class) runOperationInTxnThrowingChecked()209 public void runOperationInTxnThrowingChecked() throws IOException { 210 JpaTestEntity entity = new JpaTestEntity(); 211 entity.setText(TRANSIENT_UNIQUE_TEXT); 212 em.persist(entity); 213 214 throw new IOException(); 215 } 216 217 @Transactional runOperationInTxnThrowingUnchecked()218 public void runOperationInTxnThrowingUnchecked() { 219 JpaTestEntity entity = new JpaTestEntity(); 220 entity.setText(TRANSIENT_UNIQUE_TEXT); 221 em.persist(entity); 222 223 throw new IllegalStateException(); 224 } 225 226 @Finder(query = "from JpaTestEntity where text = :text") find(@amed"text") String text)227 public JpaTestEntity find(@Named("text") String text) { 228 return null; 229 } 230 } 231 } 232