Pluggable vendor-specific adapters for JPA providers (Hibernate, EclipseLink) that provide database platform configuration and vendor-specific JPA properties.
// PostgreSQL
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQLDialect");
// MySQL
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL8Dialect");
// Oracle
vendorAdapter.setDatabase(Database.ORACLE);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle12cDialect");
// SQL Server
vendorAdapter.setDatabase(Database.SQL_SERVER);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.SQLServerDialect");
// H2 (for testing)
vendorAdapter.setDatabase(Database.H2);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.domain");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(false); // false in production
vendorAdapter.setShowSql(false); // false in production
em.setJpaVendorAdapter(vendorAdapter);
return em;
}@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.domain");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL8Dialect");
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setShowSql(true);
vendorAdapter.setPrepareConnection(true); // Optimize read-only transactions
em.setJpaVendorAdapter(vendorAdapter);
return em;
}class HibernateJpaVendorAdapter {
// Constructor
HibernateJpaVendorAdapter();
// Connection preparation for read-only transactions
void setPrepareConnection(boolean prepareConnection);
// Inherited from AbstractJpaVendorAdapter
void setDatabase(Database database);
Database getDatabase();
void setDatabasePlatform(String databasePlatform);
String getDatabasePlatform();
void setGenerateDdl(boolean generateDdl);
boolean isGenerateDdl();
void setShowSql(boolean showSql);
boolean isShowSql();
// Access provider and dialect
PersistenceProvider getPersistenceProvider();
String getPersistenceProviderRootPackage();
Map<String, Object> getJpaPropertyMap(PersistenceUnitInfo pui);
Map<String, Object> getJpaPropertyMap();
HibernateJpaDialect getJpaDialect();
Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface();
Class<? extends EntityManager> getEntityManagerInterface();
}import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.domain");
EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
em.setJpaVendorAdapter(vendorAdapter);
return em;
}class EclipseLinkJpaVendorAdapter {
// Inherited from AbstractJpaVendorAdapter
void setDatabase(Database database);
void setDatabasePlatform(String databasePlatform);
void setGenerateDdl(boolean generateDdl);
void setShowSql(boolean showSql);
// Access provider and dialect
PersistenceProvider getPersistenceProvider();
Map<String, Object> getJpaPropertyMap();
EclipseLinkJpaDialect getJpaDialect();
Class<? extends EntityManager> getEntityManagerInterface();
}enum Database {
DEFAULT, // Use default detection
DB2, // IBM DB2
DERBY, // Apache Derby
H2, // H2 Database
HANA, // SAP HANA
HSQL, // HyperSQL
INFORMIX, // IBM Informix
MYSQL, // MySQL/MariaDB
ORACLE, // Oracle Database
POSTGRESQL, // PostgreSQL
SQL_SERVER, // Microsoft SQL Server
SYBASE // SAP Sybase
}Use with JpaTransactionManager for enhanced functionality:
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
@Bean
public JpaTransactionManager transactionManager(
EntityManagerFactory entityManagerFactory,
DataSource dataSource) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
// Configure Hibernate-specific JPA dialect
HibernateJpaDialect jpaDialect = new HibernateJpaDialect();
jpaDialect.setPrepareConnection(true);
// Custom JDBC exception translator
SQLExceptionTranslator exceptionTranslator =
new SQLErrorCodeSQLExceptionTranslator(dataSource);
jpaDialect.setJdbcExceptionTranslator(exceptionTranslator);
transactionManager.setJpaDialect(jpaDialect);
return transactionManager;
}class HibernateJpaDialect {
// Connection preparation
void setPrepareConnection(boolean prepareConnection);
// JDBC exception translator
void setJdbcExceptionTranslator(SQLExceptionTranslator translator);
// Inherited from DefaultJpaDialect
Object beginTransaction(EntityManager em, TransactionDefinition def);
Object prepareTransaction(EntityManager em, boolean readOnly, String name);
void cleanupTransaction(Object transactionData);
ConnectionHandle getJdbcConnection(EntityManager em, boolean readOnly);
DataAccessException translateExceptionIfPossible(RuntimeException ex);
}@Configuration
@EnableTransactionManagement
public class JpaConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.domain");
// Configure Hibernate vendor adapter
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setShowSql(true);
vendorAdapter.setPrepareConnection(true);
em.setJpaVendorAdapter(vendorAdapter);
// Additional JPA properties
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.format_sql", "true");
properties.put("hibernate.use_sql_comments", "true");
properties.put("hibernate.jdbc.batch_size", "20");
properties.put("hibernate.cache.use_second_level_cache", "true");
em.setJpaPropertyMap(properties);
return em;
}
@Bean
public PlatformTransactionManager transactionManager(
EntityManagerFactory entityManagerFactory,
DataSource dataSource) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
// Configure Hibernate JPA dialect
HibernateJpaDialect jpaDialect = new HibernateJpaDialect();
jpaDialect.setPrepareConnection(true);
transactionManager.setJpaDialect(jpaDialect);
return transactionManager;
}
}| Database | Dialect Class |
|---|---|
| PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
| MySQL 8.x | org.hibernate.dialect.MySQL8Dialect |
| MySQL 5.7 | org.hibernate.dialect.MySQL57Dialect |
| Oracle 12c+ | org.hibernate.dialect.Oracle12cDialect |
| SQL Server | org.hibernate.dialect.SQLServerDialect |
| H2 | org.hibernate.dialect.H2Dialect |
| HSQLDB | org.hibernate.dialect.HSQLDialect |
| Derby | org.hibernate.dialect.DerbyDialect |
| DB2 | org.hibernate.dialect.DB2Dialect |
| Database | Target Database Name |
|---|---|
| PostgreSQL | PostgreSQL |
| MySQL | MySQL |
| Oracle | Oracle |
| SQL Server | SQLServer |
| H2 | H2 |