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