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