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