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 }