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