• 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 
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