1 16 17 package org.springframework.orm.jdo; 18 19 import javax.jdo.JDODataStoreException; 20 import javax.jdo.JDOException; 21 import javax.jdo.JDOFatalDataStoreException; 22 import javax.jdo.JDOFatalUserException; 23 import javax.jdo.JDOObjectNotFoundException; 24 import javax.jdo.JDOOptimisticVerificationException; 25 import javax.jdo.JDOUserException; 26 import javax.jdo.PersistenceManager; 27 import javax.jdo.PersistenceManagerFactory; 28 import javax.jdo.Query; 29 import javax.sql.DataSource ; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 34 import org.springframework.dao.DataAccessException; 35 import org.springframework.dao.DataAccessResourceFailureException; 36 import org.springframework.jdbc.datasource.DataSourceUtils; 37 import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; 38 import org.springframework.jdbc.support.SQLExceptionTranslator; 39 import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; 40 import org.springframework.transaction.support.TransactionSynchronizationAdapter; 41 import org.springframework.transaction.support.TransactionSynchronizationManager; 42 import org.springframework.util.Assert; 43 44 59 public abstract class PersistenceManagerFactoryUtils { 60 61 67 public static final int PERSISTENCE_MANAGER_SYNCHRONIZATION_ORDER = 68 DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100; 69 70 private static final Log logger = LogFactory.getLog(PersistenceManagerFactoryUtils.class); 71 72 73 84 static SQLExceptionTranslator newJdbcExceptionTranslator(Object connectionFactory) { 85 if (connectionFactory instanceof DataSource ) { 87 return new SQLErrorCodeSQLExceptionTranslator((DataSource ) connectionFactory); 88 } 89 else { 90 return new SQLStateSQLExceptionTranslator(); 91 } 92 } 93 94 108 public static PersistenceManager getPersistenceManager(PersistenceManagerFactory pmf, boolean allowCreate) 109 throws DataAccessResourceFailureException, IllegalStateException { 110 111 try { 112 return doGetPersistenceManager(pmf, allowCreate); 113 } 114 catch (JDOException ex) { 115 throw new DataAccessResourceFailureException("Could not obtain JDO PersistenceManager", ex); 116 } 117 } 118 119 135 public static PersistenceManager doGetPersistenceManager(PersistenceManagerFactory pmf, boolean allowCreate) 136 throws JDOException, IllegalStateException { 137 138 Assert.notNull(pmf, "No PersistenceManagerFactory specified"); 139 140 PersistenceManagerHolder pmHolder = 141 (PersistenceManagerHolder) TransactionSynchronizationManager.getResource(pmf); 142 if (pmHolder != null) { 143 if (!pmHolder.isSynchronizedWithTransaction() && 144 TransactionSynchronizationManager.isSynchronizationActive()) { 145 pmHolder.setSynchronizedWithTransaction(true); 146 TransactionSynchronizationManager.registerSynchronization( 147 new PersistenceManagerSynchronization(pmHolder, pmf, false)); 148 } 149 return pmHolder.getPersistenceManager(); 150 } 151 152 if (!allowCreate && !TransactionSynchronizationManager.isSynchronizationActive()) { 153 throw new IllegalStateException ("No JDO PersistenceManager bound to thread, " + 154 "and configuration does not allow creation of non-transactional one here"); 155 } 156 157 logger.debug("Opening JDO PersistenceManager"); 158 PersistenceManager pm = pmf.getPersistenceManager(); 159 160 if (TransactionSynchronizationManager.isSynchronizationActive()) { 161 logger.debug("Registering transaction synchronization for JDO PersistenceManager"); 162 pmHolder = new PersistenceManagerHolder(pm); 165 pmHolder.setSynchronizedWithTransaction(true); 166 TransactionSynchronizationManager.registerSynchronization( 167 new PersistenceManagerSynchronization(pmHolder, pmf, true)); 168 TransactionSynchronizationManager.bindResource(pmf, pmHolder); 169 } 170 171 return pm; 172 } 173 174 182 public static boolean isPersistenceManagerTransactional( 183 PersistenceManager pm, PersistenceManagerFactory pmf) { 184 185 if (pmf == null) { 186 return false; 187 } 188 PersistenceManagerHolder pmHolder = 189 (PersistenceManagerHolder) TransactionSynchronizationManager.getResource(pmf); 190 return (pmHolder != null && pm == pmHolder.getPersistenceManager()); 191 } 192 193 201 public static void applyTransactionTimeout( 202 Query query, PersistenceManagerFactory pmf, JdoDialect jdoDialect) throws JDOException { 203 204 Assert.notNull(query, "No Query object specified"); 205 PersistenceManagerHolder pmHolder = 206 (PersistenceManagerHolder) TransactionSynchronizationManager.getResource(pmf); 207 if (pmHolder != null && pmHolder.hasTimeout()) { 208 jdoDialect.applyQueryTimeout(query, pmHolder.getTimeToLiveInSeconds()); 209 } 210 } 211 212 225 public static DataAccessException convertJdoAccessException(JDOException ex) { 226 if (ex instanceof JDOObjectNotFoundException) { 227 throw new JdoObjectRetrievalFailureException((JDOObjectNotFoundException) ex); 228 } 229 if (ex instanceof JDOOptimisticVerificationException) { 230 throw new JdoOptimisticLockingFailureException((JDOOptimisticVerificationException) ex); 231 } 232 if (ex instanceof JDODataStoreException) { 233 return new JdoResourceFailureException((JDODataStoreException) ex); 234 } 235 if (ex instanceof JDOFatalDataStoreException) { 236 return new JdoResourceFailureException((JDOFatalDataStoreException) ex); 237 } 238 if (ex instanceof JDOUserException) { 239 return new JdoUsageException((JDOUserException) ex); 240 } 241 if (ex instanceof JDOFatalUserException) { 242 return new JdoUsageException((JDOFatalUserException) ex); 243 } 244 return new JdoSystemException(ex); 246 } 247 248 255 public static void releasePersistenceManager(PersistenceManager pm, PersistenceManagerFactory pmf) { 256 try { 257 doReleasePersistenceManager(pm, pmf); 258 } 259 catch (JDOException ex) { 260 logger.debug("Could not close JDO PersistenceManager", ex); 261 } 262 catch (Throwable ex) { 263 logger.debug("Unexpected exception on closing JDO PersistenceManager", ex); 264 } 265 } 266 267 275 public static void doReleasePersistenceManager(PersistenceManager pm, PersistenceManagerFactory pmf) 276 throws JDOException { 277 278 if (pm == null) { 279 return; 280 } 281 if (!isPersistenceManagerTransactional(pm, pmf)) { 283 logger.debug("Closing JDO PersistenceManager"); 284 pm.close(); 285 } 286 } 287 288 289 294 private static class PersistenceManagerSynchronization extends TransactionSynchronizationAdapter { 295 296 private final PersistenceManagerHolder persistenceManagerHolder; 297 298 private final PersistenceManagerFactory persistenceManagerFactory; 299 300 private final boolean newPersistenceManager; 301 302 private boolean holderActive = true; 303 304 public PersistenceManagerSynchronization( 305 PersistenceManagerHolder pmHolder, PersistenceManagerFactory pmf, boolean newPersistenceManager) { 306 this.persistenceManagerHolder = pmHolder; 307 this.persistenceManagerFactory = pmf; 308 this.newPersistenceManager = newPersistenceManager; 309 } 310 311 public int getOrder() { 312 return PERSISTENCE_MANAGER_SYNCHRONIZATION_ORDER; 313 } 314 315 public void suspend() { 316 if (this.holderActive) { 317 TransactionSynchronizationManager.unbindResource(this.persistenceManagerFactory); 318 } 319 } 320 321 public void resume() { 322 if (this.holderActive) { 323 TransactionSynchronizationManager.bindResource( 324 this.persistenceManagerFactory, this.persistenceManagerHolder); 325 } 326 } 327 328 public void beforeCompletion() { 329 if (this.newPersistenceManager) { 330 TransactionSynchronizationManager.unbindResource(this.persistenceManagerFactory); 331 this.holderActive = false; 332 releasePersistenceManager( 333 this.persistenceManagerHolder.getPersistenceManager(), this.persistenceManagerFactory); 334 } 335 } 336 337 public void afterCompletion(int status) { 338 this.persistenceManagerHolder.setSynchronizedWithTransaction(false); 339 } 340 } 341 342 } 343 | Popular Tags |