001: /*
002: * Copyright 2002-2007 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: * http://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:
017: package org.springframework.orm.jpa;
018:
019: import java.io.Serializable;
020: import java.sql.SQLException;
021:
022: import javax.persistence.EntityManager;
023: import javax.persistence.EntityManagerFactory;
024: import javax.persistence.PersistenceException;
025:
026: import org.springframework.dao.DataAccessException;
027: import org.springframework.jdbc.datasource.ConnectionHandle;
028: import org.springframework.transaction.InvalidIsolationLevelException;
029: import org.springframework.transaction.TransactionDefinition;
030: import org.springframework.transaction.TransactionException;
031:
032: /**
033: * Default implementation of the {@link JpaDialect} interface.
034: * Used as default dialect by {@link JpaAccessor} and {@link JpaTransactionManager}.
035: *
036: * <p>Simply begins a standard JPA transaction in {@link #beginTransaction}
037: * and performs standard exception translation through {@link EntityManagerFactoryUtils}.
038: *
039: * @author Juergen Hoeller
040: * @since 2.0
041: * @see JpaAccessor#setJpaDialect
042: * @see JpaTransactionManager#setJpaDialect
043: */
044: public class DefaultJpaDialect implements JpaDialect, Serializable {
045:
046: //-------------------------------------------------------------------------
047: // Hooks for transaction management (used by JpaTransactionManager)
048: //-------------------------------------------------------------------------
049:
050: /**
051: * This implementation invokes the standard JPA <code>Transaction.begin</code>
052: * method. Throws an InvalidIsolationLevelException if a non-default isolation
053: * level is set.
054: * <p>This implementation does not return any transaction data Object, since there
055: * is no state to be kept for a standard JPA transaction. Hence, subclasses do not
056: * have to care about the return value (<code>null</code>) of this implementation
057: * and are free to return their own transaction data Object.
058: * @see javax.persistence.EntityTransaction#begin
059: * @see org.springframework.transaction.InvalidIsolationLevelException
060: * @see #cleanupTransaction
061: */
062: public Object beginTransaction(EntityManager entityManager,
063: TransactionDefinition definition)
064: throws PersistenceException, SQLException,
065: TransactionException {
066:
067: if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
068: throw new InvalidIsolationLevelException(
069: "Standard JPA does not support custom isolation levels - "
070: + "use a special JpaDialect for your JPA implementation");
071: }
072: entityManager.getTransaction().begin();
073: return null;
074: }
075:
076: public Object prepareTransaction(EntityManager entityManager,
077: boolean readOnly, String name) throws PersistenceException {
078:
079: return null;
080: }
081:
082: /**
083: * This implementation does nothing, since the default <code>beginTransaction</code>
084: * implementation does not require any cleanup.
085: * @see #beginTransaction
086: */
087: public void cleanupTransaction(Object transactionData) {
088: }
089:
090: /**
091: * This implementation always returns <code>null</code>,
092: * indicating that no JDBC Connection can be provided.
093: */
094: public ConnectionHandle getJdbcConnection(
095: EntityManager entityManager, boolean readOnly)
096: throws PersistenceException, SQLException {
097:
098: return null;
099: }
100:
101: /**
102: * This implementation does nothing, assuming that the Connection
103: * will implicitly be closed with the EntityManager.
104: * <p>If the JPA implementation returns a Connection handle that it expects
105: * the application to close after use, the dialect implementation needs to invoke
106: * <code>Connection.close()</code> (or some other method with similar effect) here.
107: * @see java.sql.Connection#close()
108: */
109: public void releaseJdbcConnection(ConnectionHandle conHandle,
110: EntityManager em) throws PersistenceException, SQLException {
111: }
112:
113: //-----------------------------------------------------------------------------------
114: // Hook for exception translation (used by JpaTransactionManager and JpaTemplate)
115: //-----------------------------------------------------------------------------------
116:
117: /**
118: * This implementation delegates to EntityManagerFactoryUtils.
119: * @see EntityManagerFactoryUtils#convertJpaAccessExceptionIfPossible
120: */
121: public DataAccessException translateExceptionIfPossible(
122: RuntimeException ex) {
123: return EntityManagerFactoryUtils
124: .convertJpaAccessExceptionIfPossible(ex);
125: }
126:
127: public boolean supportsEntityManagerFactoryPlusOperations() {
128: return false;
129: }
130:
131: public boolean supportsEntityManagerPlusOperations() {
132: return false;
133: }
134:
135: public EntityManagerFactoryPlusOperations getEntityManagerFactoryPlusOperations(
136: EntityManagerFactory rawEntityManager) {
137: throw new UnsupportedOperationException(
138: getClass().getName()
139: + " does not support EntityManagerFactoryPlusOperations");
140: }
141:
142: public EntityManagerPlusOperations getEntityManagerPlusOperations(
143: EntityManager rawEntityManager) {
144: throw new UnsupportedOperationException(getClass().getName()
145: + " does not support EntityManagerPlusOperations");
146: }
147:
148: }
|