001/** 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.apache.tapestry5.internal.jpa; 015 016import java.util.HashMap; 017import java.util.Map; 018 019import javax.persistence.EntityManager; 020 021import org.apache.tapestry5.ioc.Invokable; 022import org.apache.tapestry5.ioc.ScopeConstants; 023import org.apache.tapestry5.ioc.annotations.Scope; 024import org.apache.tapestry5.jpa.EntityManagerManager; 025import org.apache.tapestry5.jpa.EntityTransactionManager; 026import org.slf4j.Logger; 027 028@Scope(ScopeConstants.PERTHREAD) 029public class EntityTransactionManagerImpl implements EntityTransactionManager 030{ 031 032 private final Logger logger; 033 private final EntityManagerManager entityManagerManager; 034 035 private final Map<String, PersistenceContextSpecificEntityTransactionManager> transactionManagerMap; 036 037 public EntityTransactionManagerImpl(Logger logger, EntityManagerManager entityManagerManager) 038 { 039 this.logger = logger; 040 this.entityManagerManager = entityManagerManager; 041 transactionManagerMap = new HashMap<>(entityManagerManager.getEntityManagers().size()); 042 } 043 044 private EntityManager getEntityManager(String unitName) 045 { 046 // EntityManager em = JpaInternalUtils.getEntityManager(entityManagerManager, unitName); 047 // FIXME we should simply incorporate the logic in JpaInternalUtils.getEntityManager to 048 // EntityManagerManager.getEntityManager(unitName) 049 if (unitName != null) 050 return entityManagerManager.getEntityManager(unitName); 051 else 052 { 053 Map<String, EntityManager> entityManagers = entityManagerManager.getEntityManagers(); 054 if (entityManagers.size() == 1) 055 return entityManagers.values().iterator().next(); 056 else 057 throw new RuntimeException( 058 "Unable to locate a single EntityManager. " 059 + "You must provide the persistence unit name as defined in the persistence.xml using the @PersistenceContext annotation."); 060 } 061 } 062 063 /* 064 * (non-Javadoc) 065 * @see net.satago.tapestry5.jpa.EntityTransactionManager#runInTransaction(java.lang.String, 066 * java.lang.Runnable) 067 */ 068 @SuppressWarnings("unchecked") 069 @Override 070 public void runInTransaction(final String unitName, final Runnable runnable) 071 { 072 getPersistenceContextSpecificEntityTransactionManager(unitName).invokeInTransaction( 073 new VoidInvokable(runnable)); 074 } 075 076 /* 077 * (non-Javadoc) 078 * @see net.satago.tapestry5.jpa.EntityTransactionManager#invokeInTransaction(java.lang.String, 079 * org.apache.tapestry5.ioc.Invokable) 080 */ 081 @Override 082 public <T> T invokeInTransaction(String unitName, Invokable<T> invokable) 083 { 084 return getPersistenceContextSpecificEntityTransactionManager(unitName).invokeInTransaction( 085 invokable); 086 } 087 088 private PersistenceContextSpecificEntityTransactionManager getPersistenceContextSpecificEntityTransactionManager( 089 String unitName) 090 { 091 if (!transactionManagerMap.containsKey(unitName)) 092 { 093 PersistenceContextSpecificEntityTransactionManager transactionManager = new PersistenceContextSpecificEntityTransactionManager( 094 logger, getEntityManager(unitName)); 095 transactionManagerMap.put(unitName, transactionManager); 096 return transactionManager; 097 } 098 else 099 return transactionManagerMap.get(unitName); 100 } 101 102 /* 103 * (non-Javadoc) 104 * @see 105 * net.satago.tapestry5.jpa.EntityTransactionManager#invokeBeforeCommit(org.apache.tapestry5 106 * .ioc.Invokable, java.lang.String) 107 */ 108 @Override 109 public void invokeBeforeCommit(String unitName, Invokable<Boolean> invokable) 110 { 111 getPersistenceContextSpecificEntityTransactionManager(unitName).addBeforeCommitInvokable( 112 invokable); 113 } 114 115 /* 116 * (non-Javadoc) 117 * @see 118 * net.satago.tapestry5.jpa.EntityTransactionManager#invokeAfterCommit(org.apache.tapestry5. 119 * ioc.Invokable, java.lang.String) 120 */ 121 @Override 122 public void invokeAfterCommit(String unitName, Invokable<Boolean> invokable) 123 { 124 getPersistenceContextSpecificEntityTransactionManager(unitName).addAfterCommitInvokable( 125 invokable); 126 127 } 128}