001/* 002 * Copyright 2002-2013 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.orm.jdo; 018 019import java.sql.SQLException; 020import javax.jdo.JDOException; 021import javax.jdo.PersistenceManager; 022import javax.jdo.Transaction; 023 024import org.springframework.dao.DataAccessException; 025import org.springframework.jdbc.datasource.ConnectionHandle; 026import org.springframework.transaction.TransactionDefinition; 027import org.springframework.transaction.TransactionException; 028 029/** 030 * SPI strategy that allows for customizing integration with a specific JDO provider, 031 * in particular regarding transaction management and exception translation. To be 032 * implemented for specific JDO providers such as JPOX, Kodo, Lido, Versant Open Access. 033 * 034 * <p>JDO 3.0 defines standard ways for most of the functionality covered here. 035 * Hence, Spring's {@link DefaultJdoDialect} uses the corresponding JDO 3.0 methods 036 * by default, to be overridden in a vendor-specific fashion if necessary. 037 * Vendor-specific subclasses of {@link DefaultJdoDialect} are still required for special 038 * transaction semantics and more sophisticated exception translation (if needed). 039 * 040 * <p>In general, it is recommended to derive from {@link DefaultJdoDialect} instead 041 * of implementing this interface directly. This allows for inheriting common 042 * behavior (present and future) from {@link DefaultJdoDialect}, only overriding 043 * specific hooks to plug in concrete vendor-specific behavior. 044 * 045 * @author Juergen Hoeller 046 * @since 02.11.2003 047 * @see JdoTransactionManager#setJdoDialect 048 * @see DefaultJdoDialect 049 */ 050public interface JdoDialect { 051 052 //------------------------------------------------------------------------- 053 // Hooks for transaction management (used by JdoTransactionManager) 054 //------------------------------------------------------------------------- 055 056 /** 057 * Begin the given JDO transaction, applying the semantics specified by the 058 * given Spring transaction definition (in particular, an isolation level 059 * and a timeout). Invoked by JdoTransactionManager on transaction begin. 060 * <p>An implementation can configure the JDO Transaction object and then 061 * invoke {@code begin}, or invoke a special begin method that takes, 062 * for example, an isolation level. 063 * <p>An implementation can also apply read-only flag and isolation level to the 064 * underlying JDBC Connection before beginning the transaction. In that case, 065 * a transaction data object can be returned that holds the previous isolation 066 * level (and possibly other data), to be reset in {@code cleanupTransaction}. 067 * <p>Implementations can also use the Spring transaction name, as exposed by the 068 * passed-in TransactionDefinition, to optimize for specific data access use cases 069 * (effectively using the current transaction name as use case identifier). 070 * @param transaction the JDO transaction to begin 071 * @param definition the Spring transaction definition that defines semantics 072 * @return an arbitrary object that holds transaction data, if any 073 * (to be passed into cleanupTransaction) 074 * @throws JDOException if thrown by JDO methods 075 * @throws SQLException if thrown by JDBC methods 076 * @throws TransactionException in case of invalid arguments 077 * @see #cleanupTransaction 078 * @see javax.jdo.Transaction#begin 079 * @see org.springframework.jdbc.datasource.DataSourceUtils#prepareConnectionForTransaction 080 */ 081 Object beginTransaction(Transaction transaction, TransactionDefinition definition) 082 throws JDOException, SQLException, TransactionException; 083 084 /** 085 * Clean up the transaction via the given transaction data. 086 * Invoked by JdoTransactionManager on transaction cleanup. 087 * <p>An implementation can, for example, reset read-only flag and 088 * isolation level of the underlying JDBC Connection. Furthermore, 089 * an exposed data access use case can be reset here. 090 * @param transactionData arbitrary object that holds transaction data, if any 091 * (as returned by beginTransaction) 092 * @see #beginTransaction 093 * @see org.springframework.jdbc.datasource.DataSourceUtils#resetConnectionAfterTransaction 094 */ 095 void cleanupTransaction(Object transactionData); 096 097 /** 098 * Retrieve the JDBC Connection that the given JDO PersistenceManager uses underneath, 099 * if accessing a relational database. This method will just get invoked if actually 100 * needing access to the underlying JDBC Connection, usually within an active JDO 101 * transaction (for example, by JdoTransactionManager). The returned handle will 102 * be passed into the {@code releaseJdbcConnection} method when not needed anymore. 103 * <p>Implementations are encouraged to return an unwrapped Connection object, i.e. 104 * the Connection as they got it from the connection pool. This makes it easier for 105 * application code to get at the underlying native JDBC Connection, like an 106 * OracleConnection, which is sometimes necessary for LOB handling etc. We assume 107 * that calling code knows how to properly handle the returned Connection object. 108 * <p>In a simple case where the returned Connection will be auto-closed with the 109 * PersistenceManager or can be released via the Connection object itself, an 110 * implementation can return a SimpleConnectionHandle that just contains the 111 * Connection. If some other object is needed in {@code releaseJdbcConnection}, 112 * an implementation should use a special handle that references that other object. 113 * @param pm the current JDO PersistenceManager 114 * @param readOnly whether the Connection is only needed for read-only purposes 115 * @return a handle for the JDBC Connection, to be passed into 116 * {@code releaseJdbcConnection}, or {@code null} 117 * if no JDBC Connection can be retrieved 118 * @throws JDOException if thrown by JDO methods 119 * @throws SQLException if thrown by JDBC methods 120 * @see #releaseJdbcConnection 121 * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection 122 * @see org.springframework.jdbc.datasource.SimpleConnectionHandle 123 * @see JdoTransactionManager#setDataSource 124 * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor 125 */ 126 ConnectionHandle getJdbcConnection(PersistenceManager pm, boolean readOnly) 127 throws JDOException, SQLException; 128 129 /** 130 * Release the given JDBC Connection, which has originally been retrieved 131 * via {@code getJdbcConnection}. This should be invoked in any case, 132 * to allow for proper release of the retrieved Connection handle. 133 * <p>An implementation might simply do nothing, if the Connection returned 134 * by {@code getJdbcConnection} will be implicitly closed when the JDO 135 * transaction completes or when the PersistenceManager is closed. 136 * @param conHandle the JDBC Connection handle to release 137 * @param pm the current JDO PersistenceManager 138 * @throws JDOException if thrown by JDO methods 139 * @throws SQLException if thrown by JDBC methods 140 * @see #getJdbcConnection 141 */ 142 void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm) 143 throws JDOException, SQLException; 144 145 146 //----------------------------------------------------------------------------------- 147 // Hook for exception translation (used by JdoTransactionManager) 148 //----------------------------------------------------------------------------------- 149 150 /** 151 * Translate the given JDOException to a corresponding exception from Spring's 152 * generic DataAccessException hierarchy. An implementation should apply 153 * PersistenceManagerFactoryUtils' standard exception translation if can't do 154 * anything more specific. 155 * <p>Of particular importance is the correct translation to 156 * DataIntegrityViolationException, for example on constraint violation. 157 * Unfortunately, standard JDO does not allow for portable detection of this. 158 * <p>Can use a SQLExceptionTranslator for translating underlying SQLExceptions 159 * in a database-specific fashion. 160 * @param ex the JDOException thrown 161 * @return the corresponding DataAccessException (must not be {@code null}) 162 * @see JdoTransactionManager#convertJdoAccessException 163 * @see PersistenceManagerFactoryUtils#convertJdoAccessException 164 * @see org.springframework.dao.DataIntegrityViolationException 165 * @see org.springframework.jdbc.support.SQLExceptionTranslator 166 */ 167 DataAccessException translateException(JDOException ex); 168 169}