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