• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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