Spring JPA with Hibernate
Spring JPA with Hibernate
Section titled “Spring JPA with Hibernate”This page covers Spring JPA backed by Hibernate.
Configure LocalContainerEntityManagerFactoryBean with the same DataSource
used by Kaumei JDBC.
Add setJpaDialect(new HibernateJpaDialect()) so Spring knows how to access the Hibernate session.
With that in place DataSourceUtils.getConnection returns the transaction-bound connection.
Flush the session before executing native SQL to ensure pending entity changes reach the database.
Implement a JdbcConnectionProvider that flushes the session and exposes the connection:
public class JpaConnectionProvider implements JdbcConnectionProvider { private final EntityManager entityManager; private final DataSource dataSource;
public JpaConnectionProvider(EntityManager entityManager, DataSource dataSource) { var jpaDialect = entityManager.getEntityManagerFactory() instanceof EntityManagerFactoryInfo info ? info.getJpaDialect() : null; if (jpaDialect == null) { throw new IllegalArgumentException("JPA Dialect not found"); } else if (jpaDialect instanceof HibernateJpaDialect) { this.entityManager = entityManager; this.dataSource = requireNonNull(dataSource); } else { throw new IllegalArgumentException("Not supported JPA Dialect: " + jpaDialect.getClass().getCanonicalName()); } }
@Override public Connection getConnection() { entityManager.flush(); return DataSourceUtils.getConnection(dataSource); }}Inject the provider into your generated classes via the Spring configuration:
@BeanAbstractEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { var entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setJpaDialect(new HibernateJpaDialect()); entityManagerFactory.setDataSource(dataSource); entityManagerFactory.setPersistenceProvider(new HibernatePersistenceProvider()); return entityManagerFactory;}
@BeanPlatformTransactionManager jpaTransactionManager( EntityManagerFactory entityManagerFactory, DataSource dataSource) { var transactionManager = new JpaTransactionManager(entityManagerFactory); transactionManager.setDataSource(dataSource); return transactionManager;}
@BeanJdbcConnectionProvider jpaConnectionProvider( EntityManager entityManager, DataSource dataSource) { return new JpaConnectionProvider(entityManager, dataSource);}
@BeanTradeRepository tradeRepositoryKaumei(JdbcConnectionProvider provider) { return new TradeRepositoryKaumei$Jdbc(provider);}The example combines JPA and Kaumei JDBC in both directions inside one
@Transactional service method.
Its duplicate-UTI rollback verifies that the pending customer change and the
Kaumei JDBC trade insert share the same Spring transaction.
References
Section titled “References”Other frameworks
Section titled “Other frameworks”This configuration has not been tested beyond Spring.
Frameworks that expose a Hibernate-backed EntityManager and a
transaction-bound DataSource can reuse the same pattern.