Add Hibernate 7 batches 2-6, batch 7, and batch 8: mapping styles, JPA annotations, natural IDs, @Immutable, stored procedures, in-memory test databases, JNDI mocking, proxies, associations, temporal mapping, named queries, HQL, Criteria API, EntityManager bootstrapping, Ehcache 3 L2 cache configuration, HikariCP connection pooling, Hibernate Validator CDI integration, aggregate functions, sorting, pagination, interceptors, and Hibernate Search 8 (Hibernate 7.4.5.Final + Spring Boot 4.1.1 + JDK 25)
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package com.ankurm.hibernatedemo.hikari;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The non-Spring side of this chapter: a plain {@code StandardServiceRegistry} -- no Spring Boot
|
||||
* autoconfiguration anywhere -- explicitly wired to HikariCP via {@code hibernate-hikaricp}
|
||||
* (the {@code org.hibernate.orm:hibernate-hikaricp} integration jar, added to this project's
|
||||
* {@code pom.xml} test scope specifically for this chapter). This is the style a Java SE
|
||||
* application, a batch job, or the original article's own non-Spring example would use.
|
||||
*
|
||||
* <p>{@code hibernate.connection.provider_class} accepts the short name {@code hikari} or {@code
|
||||
* hikaricp} (both registered, confirmed by disassembling {@code
|
||||
* StrategyRegistrationProviderImpl.class} in {@code hibernate-hikaricp-7.4.5.Final.jar}) as well
|
||||
* as the fully-qualified {@code org.hibernate.hikaricp.internal.HikariCPConnectionProvider}.
|
||||
* Every {@code hibernate.hikari.*}-prefixed setting (confirmed via the same jar's {@code
|
||||
* HikariConfigurationUtil.CONFIG_PREFIX} constant, {@code "hibernate.hikari."}) is copied
|
||||
* directly onto the underlying {@code HikariConfig} by property name -- {@code
|
||||
* hibernate.hikari.maximumPoolSize} sets {@code HikariConfig#setMaximumPoolSize}, {@code
|
||||
* hibernate.hikari.poolName} sets {@code HikariConfig#setPoolName}, and so on.
|
||||
*
|
||||
* <p>Docs: docs/19-hikaricp-connection-pooling.md
|
||||
*/
|
||||
class HikariRawBootstrapTest {
|
||||
|
||||
private StandardServiceRegistry registry;
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
if (sessionFactory != null) {
|
||||
sessionFactory.close();
|
||||
}
|
||||
if (registry != null) {
|
||||
StandardServiceRegistryBuilder.destroy(registry);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void rawStandardServiceRegistry_wiredToHikariByShortName_actuallyUsesHikariUnderneath() {
|
||||
registry = new StandardServiceRegistryBuilder()
|
||||
.applySetting("hibernate.connection.driver_class", "org.h2.Driver")
|
||||
.applySetting("hibernate.connection.url", "jdbc:h2:mem:hikarirawbootstrap;DB_CLOSE_DELAY=-1")
|
||||
.applySetting("hibernate.connection.username", "sa")
|
||||
.applySetting("hibernate.hbm2ddl.auto", "create")
|
||||
.applySetting("hibernate.connection.provider_class", "hikari")
|
||||
.applySetting("hibernate.hikari.maximumPoolSize", "7")
|
||||
.applySetting("hibernate.hikari.poolName", "hibernate-demo-ch19-pool")
|
||||
.applySetting("hibernate.hikari.connectionTimeout", "5000")
|
||||
.build();
|
||||
Metadata metadata = new MetadataSources(registry)
|
||||
.addAnnotatedClass(PoolProbe.class)
|
||||
.buildMetadata();
|
||||
sessionFactory = metadata.buildSessionFactory();
|
||||
|
||||
ConnectionProvider provider = sessionFactory.unwrap(SessionFactoryImplementor.class)
|
||||
.getServiceRegistry()
|
||||
.getService(ConnectionProvider.class);
|
||||
|
||||
System.out.println("RESULT[hikari-raw-bootstrap]: ConnectionProvider class="
|
||||
+ provider.getClass().getName()
|
||||
+ " | isUnwrappableAs(HikariDataSource)=" + provider.isUnwrappableAs(HikariDataSource.class));
|
||||
|
||||
assertThat(provider.getClass().getName())
|
||||
.as("hibernate.connection.provider_class=hikari resolves to the real HikariCP integration")
|
||||
.isEqualTo("org.hibernate.hikaricp.internal.HikariCPConnectionProvider");
|
||||
assertThat(provider.isUnwrappableAs(HikariDataSource.class)).isTrue();
|
||||
|
||||
HikariDataSource hikari = provider.unwrap(HikariDataSource.class);
|
||||
|
||||
System.out.println("RESULT[hikari-raw-bootstrap-config]: poolName=" + hikari.getPoolName()
|
||||
+ " | maximumPoolSize=" + hikari.getMaximumPoolSize()
|
||||
+ " | connectionTimeout=" + hikari.getConnectionTimeout() + "ms"
|
||||
+ " -- every value traces back to a hibernate.hikari.* setting passed into "
|
||||
+ "StandardServiceRegistryBuilder, with zero Spring involved.");
|
||||
|
||||
assertThat(hikari.getPoolName()).isEqualTo("hibernate-demo-ch19-pool");
|
||||
assertThat(hikari.getMaximumPoolSize()).isEqualTo(7);
|
||||
assertThat(hikari.getConnectionTimeout()).isEqualTo(5000L);
|
||||
|
||||
// Prove the pool is actually live, not just configured: persist through it.
|
||||
try (var session = sessionFactory.openSession()) {
|
||||
var tx = session.beginTransaction();
|
||||
session.persist(new PoolProbe("raw-bootstrap-probe"));
|
||||
tx.commit();
|
||||
}
|
||||
assertThat(hikari.getHikariPoolMXBean().getTotalConnections())
|
||||
.as("the pool actually opened at least one real connection to service that persist()")
|
||||
.isGreaterThanOrEqualTo(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user