001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.persistence;
019
020 import java.util.Map;
021
022 import javax.persistence.*;
023 import javax.persistence.TransactionRequiredException;
024 import javax.transaction.*;
025 import org.apache.geronimo.transaction.manager.TransactionImpl;
026 import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
027
028 /**
029 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
030 */
031 public class CMPEntityManagerTxScoped implements EntityManager {
032
033 private final TransactionManagerImpl transactionManager;
034 private final String persistenceUnit;
035 private final EntityManagerFactory entityManagerFactory;
036 private final Map entityManagerProperties;
037
038 public CMPEntityManagerTxScoped(TransactionManagerImpl transactionManager, String persistenceUnit, EntityManagerFactory entityManagerFactory, Map entityManagerProperties) {
039 this.transactionManager = transactionManager;
040 this.persistenceUnit = persistenceUnit;
041 this.entityManagerFactory = entityManagerFactory;
042 this.entityManagerProperties = entityManagerProperties;
043 }
044
045 private EntityManager getEntityManager(boolean activeRequired) {
046 TransactionImpl transaction = (TransactionImpl) transactionManager.getTransaction();
047 if (activeRequired && (transaction == null || transaction.getStatus() != Status.STATUS_ACTIVE)) {
048 throw new TransactionRequiredException("No active transaction");
049 }
050 if (transaction == null) {
051 return null;
052 }
053 EntityManagerWrapper entityManagerWrapper = (EntityManagerWrapper) transactionManager.getResource(persistenceUnit);
054 if (entityManagerWrapper == null) {
055 EntityManager entityManager = createEntityManager();
056 entityManagerWrapper = new EntityManagerWrapperTxScoped(entityManager);
057 transactionManager.putResource(persistenceUnit, entityManagerWrapper);
058 try {
059 transaction.registerSynchronization(entityManagerWrapper);
060 } catch (javax.transaction.RollbackException e) {
061 throw (TransactionRequiredException) new TransactionRequiredException("No active transaction").initCause(e);
062 } catch (SystemException e) {
063 throw (TransactionRequiredException) new TransactionRequiredException("No active transaction").initCause(e);
064 }
065 }
066 return entityManagerWrapper.getEntityManager();
067 }
068
069 private EntityManager createEntityManager() {
070 EntityManager entityManager;
071 if (entityManagerProperties == null) {
072 entityManager = entityManagerFactory.createEntityManager();
073 } else {
074 entityManager = entityManagerFactory.createEntityManager(entityManagerProperties);
075 }
076 return entityManager;
077 }
078
079
080 public void persist(Object o) {
081 EntityManager entityManager = getEntityManager(true);
082 if (entityManager != null) {
083 entityManager.persist(o);
084 } else {
085 entityManager = createEntityManager();
086 try {
087 entityManager.persist(o);
088 } finally {
089 entityManager.close();
090 }
091 }
092 }
093
094 public <T> T merge(T t) {
095 EntityManager entityManager = getEntityManager(true);
096 if (entityManager != null) {
097 return entityManager.merge(t);
098 } else {
099 entityManager = createEntityManager();
100 try {
101 return entityManager.merge(t);
102 } finally {
103 entityManager.close();
104 }
105 }
106 }
107
108 public void remove(Object o) {
109 EntityManager entityManager = getEntityManager(true);
110 if (entityManager != null) {
111 entityManager.remove(o);
112 } else {
113 entityManager = createEntityManager();
114 try {
115 entityManager.remove(o);
116 } finally {
117 entityManager.close();
118 }
119 }
120 }
121
122 public <T> T find(Class<T> aClass, Object o) {
123 EntityManager entityManager = getEntityManager(false);
124 if (entityManager != null) {
125 return entityManager.find(aClass, o);
126 } else {
127 entityManager = createEntityManager();
128 try {
129 return entityManager.find(aClass, o);
130 } finally {
131 entityManager.close();
132 }
133 }
134 }
135
136 public <T> T getReference(Class<T> aClass, Object o) {
137 EntityManager entityManager = getEntityManager(false);
138 if (entityManager != null) {
139 return entityManager.getReference(aClass, o);
140 } else {
141 entityManager = createEntityManager();
142 try {
143 return entityManager.getReference(aClass, o);
144 } finally {
145 entityManager.close();
146 }
147 }
148 }
149
150 public void flush() {
151 EntityManager entityManager = getEntityManager(false);
152 if (entityManager != null) {
153 entityManager.flush();
154 } else {
155 entityManager = createEntityManager();
156 try {
157 entityManager.flush();
158 } finally {
159 entityManager.close();
160 }
161 }
162 }
163
164 public void setFlushMode(FlushModeType flushModeType) {
165 EntityManager entityManager = getEntityManager(false);
166 if (entityManager != null) {
167 entityManager.setFlushMode(flushModeType);
168 } else {
169 entityManager = createEntityManager();
170 try {
171 entityManager.setFlushMode(flushModeType);
172 } finally {
173 entityManager.close();
174 }
175 }
176 }
177
178 public FlushModeType getFlushMode() {
179 EntityManager entityManager = getEntityManager(false);
180 if (entityManager != null) {
181 return entityManager.getFlushMode();
182 } else {
183 entityManager = createEntityManager();
184 try {
185 return entityManager.getFlushMode();
186 } finally {
187 entityManager.close();
188 }
189 }
190 }
191
192 public void lock(Object o, LockModeType lockModeType) {
193 EntityManager entityManager = getEntityManager(false);
194 if (entityManager != null) {
195 entityManager.lock(o, lockModeType);
196 } else {
197 entityManager = createEntityManager();
198 try {
199 entityManager.lock(o, lockModeType);
200 } finally {
201 entityManager.close();
202 }
203 }
204 }
205
206 public void refresh(Object o) {
207 EntityManager entityManager = getEntityManager(true);
208 if (entityManager != null) {
209 entityManager.refresh(o);
210 } else {
211 entityManager = createEntityManager();
212 try {
213 entityManager.refresh(o);
214 } finally {
215 entityManager.close();
216 }
217 }
218 }
219
220 public void clear() {
221 EntityManager entityManager = getEntityManager(false);
222 if (entityManager != null) {
223 entityManager.clear();
224 } else {
225 entityManager = createEntityManager();
226 try {
227 entityManager.clear();
228 } finally {
229 entityManager.close();
230 }
231 }
232 }
233
234 public boolean contains(Object o) {
235 EntityManager entityManager = getEntityManager(false);
236 if (entityManager != null) {
237 return entityManager.contains(o);
238 } else {
239 entityManager = createEntityManager();
240 try {
241 return entityManager.contains(o);
242 } finally {
243 entityManager.close();
244 }
245 }
246 }
247
248 public Query createQuery(String s) {
249 EntityManager entityManager = getEntityManager(false);
250 if (entityManager != null) {
251 return entityManager.createQuery(s);
252 } else {
253 entityManager = createEntityManager();
254 return new NoTxQueryWrapper(entityManager, entityManager.createQuery(s));
255 }
256 }
257
258 public Query createNamedQuery(String s) {
259 EntityManager entityManager = getEntityManager(false);
260 if (entityManager != null) {
261 return entityManager.createNamedQuery(s);
262 } else {
263 entityManager = createEntityManager();
264 return new NoTxQueryWrapper(entityManager, entityManager.createNamedQuery(s));
265 }
266 }
267
268 public Query createNativeQuery(String s) {
269 EntityManager entityManager = getEntityManager(false);
270 if (entityManager != null) {
271 return entityManager.createNativeQuery(s);
272 } else {
273 entityManager = createEntityManager();
274 return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s));
275 }
276 }
277
278 public Query createNativeQuery(String s, Class aClass) {
279 EntityManager entityManager = getEntityManager(false);
280 if (entityManager != null) {
281 return entityManager.createNativeQuery(s, aClass);
282 } else {
283 entityManager = createEntityManager();
284 return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s, aClass));
285 }
286 }
287
288 public Query createNativeQuery(String s, String s1) {
289 EntityManager entityManager = getEntityManager(false);
290 if (entityManager != null) {
291 return entityManager.createNativeQuery(s, s1);
292 } else {
293 entityManager = createEntityManager();
294 return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s, s1));
295 }
296 }
297
298 public void close() {
299 throw new IllegalStateException("You cannot call close on a Container Managed Entity Manager");
300 }
301
302 public boolean isOpen() {
303 return true;
304 }
305
306 public EntityTransaction getTransaction() {
307 throw new IllegalStateException("You cannot call getTransaction on a container managed EntityManager");
308 }
309
310 public void joinTransaction() {
311 throw new IllegalStateException("You cannot call joinTransaction on a container managed EntityManager");
312 }
313
314 public Object getDelegate() {
315 EntityManager entityManager = getEntityManager(false);
316 if (entityManager != null) {
317 return entityManager.getDelegate();
318 } else {
319 entityManager = createEntityManager();
320 try {
321 return entityManager.getDelegate();
322 } finally {
323 entityManager.close();
324 }
325 }
326 }
327
328 private static class EntityManagerWrapperTxScoped implements EntityManagerWrapper, Synchronization {
329 private final EntityManager entityManager;
330
331 public EntityManagerWrapperTxScoped(EntityManager entityManager) {
332 if (entityManager == null) {
333 throw new IllegalArgumentException("Need a non-null entity manager");
334 }
335 this.entityManager = entityManager;
336 }
337
338 public void close() {
339 entityManager.close();
340 }
341
342 public EntityManager getEntityManager() {
343 return entityManager;
344 }
345
346 public void beforeCompletion() {
347 }
348
349 public void afterCompletion(int i) {
350 close();
351 }
352 }
353 }