Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/run-hibernate-orm-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
steps:
- name: 'Clone repository'
uses: actions/checkout@v6
with:
fetch-depth: 50
- name: 'Get changed files'
id: changed-files-specific
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.1
Expand All @@ -33,11 +31,11 @@ jobs:
id: changed-files
if: ${{steps.changed-files-specific.outputs.doc_only_changed == 'false' && steps.changed-files-specific.outputs.doc_only_modified == 'false'}}
run: echo "ONLY_DOCS=false" >> $GITHUB_OUTPUT
- name: 'Set up JDK 8'
- name: 'Set up JDK 24'
uses: actions/setup-java@v5
with:
distribution: 'corretto'
java-version: 8
java-version: 24
- name: 'Run Hibernate ORM integration tests'
if: ${{steps.changed-files.outputs.ONLY_DOCS && steps.changed-files.outputs.ONLY_DOCS == 'false'}}
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
In this tutorial, you will set up a Spring Boot and Hibernate application with the AWS Advanced JDBC Wrapper, and use a single datasource to fetch and update data from an Aurora PostgreSQL database. The datasource is configured to provide a writer connection or a reader connection to off-load a writer node from read-only queries. It provides pooled connections through the AWS Advanced JDBC Wrapper internal connection pool configuration.

> Note: this tutorial was written using the following technologies:
> - Spring Boot 2.7.1
> - Hibernate
> - AWS Advanced JDBC Wrapper 2.3.2
> - Postgresql 42.5.4
> - Gradle 7
> - Java 11
> - Spring Boot 3.4.4
> - Hibernate 6.x (via Spring Boot)
> - AWS Advanced JDBC Wrapper 3.2.0
> - Postgresql 42.7.10
> - Gradle 8
> - Java 17

You will progress through the following sections:
1. Create a Gradle Spring Boot project
Expand Down Expand Up @@ -68,7 +68,7 @@ Configure Spring to use the AWS Advanced JDBC Wrapper as the default datasource.
driver-class-name: software.amazon.jdbc.Driver
type: org.springframework.jdbc.datasource.SimpleDriverDataSource
```
2. The datasource mentioned above does not use Hikari datasource that is default for Spring 2+ application. The AWS Advanced JDBC Wrapper manages its own internal connection pool (or several connection pools, if needed), which increases overall efficiency and helps facilitate failover support. All necessary configuration parameters are defined in the `F0` configuration profile. Other configuration presets `D`, `E` and `F` can be used as well. Any configuration profile or preset specified should use the [Read/Write Splitting Plugin](../../docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md). More details are available at [Configuration Profiles](../../docs/using-the-jdbc-driver/UsingTheJdbcDriver.md#configuration-profiles) and [Configuration Presets](../../docs/using-the-jdbc-driver/ConfigurationPresets.md).
2. The datasource mentioned above does not use Hikari datasource that is default for Spring Boot 3+ application. The AWS Advanced JDBC Wrapper manages its own internal connection pool (or several connection pools, if needed), which increases overall efficiency and helps facilitate failover support. All necessary configuration parameters are defined in the `F0` configuration profile. Other configuration presets `D`, `E` and `F` can be used as well. Any configuration profile or preset specified should use the [Read/Write Splitting Plugin](../../docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md). More details are available at [Configuration Profiles](../../docs/using-the-jdbc-driver/UsingTheJdbcDriver.md#configuration-profiles) and [Configuration Presets](../../docs/using-the-jdbc-driver/ConfigurationPresets.md).
<br><br>
Including the optional configuration parameter `readerHostSelectorStrategy` in the connection string helps to set up a strategy to select a reader node. Possible values are `random`, `roundRobin` and `leastConnections`. More details are available at [Reader Selection Strategies](../../docs/using-the-jdbc-driver/HostSelectionStrategies.md).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@
*/

plugins {
id("org.springframework.boot") version "2.7.0"
id("org.springframework.boot") version "3.4.4"
id("io.spring.dependency-management") version "1.1.7"
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.retry:spring-retry")
implementation("org.postgresql:postgresql:42.7.7")
implementation("software.amazon.awssdk:rds:2.42.4")
implementation("org.postgresql:postgresql:42.7.10")
implementation("software.amazon.awssdk:rds:2.42.15")
implementation(project(":aws-advanced-jdbc-wrapper"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package example.data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Book {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
In this tutorial, you will set up a Spring Boot and Hibernate application with the AWS Advanced JDBC Wrapper, and use two datasources to fetch and update data from an Aurora PostgreSQL database. One datasource is configured to provide a writer connection. The other datasource is configured to provide a reader connection to off load a writer node from read-only queries. Both datasources provide pooled connections through AWS Advanced JDBC Wrapper internal connection pool configuration.

> Note: this tutorial was written using the following technologies:
> - Spring Boot 2.7.1
> - Hibernate
> - AWS Advanced JDBC Wrapper 2.3.2
> - Postgresql 42.5.4
> - Gradle 7
> - Java 11
> - Spring Boot 3.4.4
> - Hibernate 6.x (via Spring Boot)
> - AWS Advanced JDBC Wrapper 3.2.0
> - Postgresql 42.7.10
> - Gradle 8
> - Java 17

You will progress through the following sections:
1. Create a Gradle Spring Boot project
Expand Down Expand Up @@ -78,7 +78,7 @@ Configure Spring to use the AWS Advanced JDBC Wrapper as the default datasource.
driver-class-name: software.amazon.jdbc.Driver
type: org.springframework.jdbc.datasource.SimpleDriverDataSource
```
2. The datasources mentioned above do not use Hikari datasources which are the default for Spring 2+ applications. The AWS Advanced JDBC Wrapper manages its own internal connection pool (or several connection pools, if needed), which increases overall efficiency and helps facilitate failover support. All necessary configuration parameters are defined in `SF_F0` configuration profile. Other configuration presets from `SF_` family can be used as well. More details are available at [Configuration Profiles](../../docs/using-the-jdbc-driver/UsingTheJdbcDriver.md#configuration-profiles) and [Configuration Presets](../../docs/using-the-jdbc-driver/ConfigurationPresets.md).
2. The datasources mentioned above do not use Hikari datasources which are the default for Spring Boot 3+ applications. The AWS Advanced JDBC Wrapper manages its own internal connection pool (or several connection pools, if needed), which increases overall efficiency and helps facilitate failover support. All necessary configuration parameters are defined in `SF_F0` configuration profile. Other configuration presets from `SF_` family can be used as well. More details are available at [Configuration Profiles](../../docs/using-the-jdbc-driver/UsingTheJdbcDriver.md#configuration-profiles) and [Configuration Presets](../../docs/using-the-jdbc-driver/ConfigurationPresets.md).
<br><br>
Optional configuration parameter `readerInitialConnectionHostSelectorStrategy` in connection string helps to setup a strategy selecting a reader node. Possible values are `random`, `roundRobin` and `leastConnections`. More details are available at [Reader Selection Strategies](../../docs/using-the-jdbc-driver/HostSelectionStrategies.md).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@
*/

plugins {
id("org.springframework.boot") version "2.7.0"
id("org.springframework.boot") version "3.4.4"
id("io.spring.dependency-management") version "1.1.7"
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.retry:spring-retry")
implementation("org.postgresql:postgresql:42.7.7")
implementation("software.amazon.awssdk:rds:2.42.4")
implementation("org.postgresql:postgresql:42.7.10")
implementation("software.amazon.awssdk:rds:2.42.15")
implementation(project(":aws-advanced-jdbc-wrapper"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package example.data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Book {
Expand Down
18 changes: 9 additions & 9 deletions examples/SpringHibernateExample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
In this tutorial, you will set up a Spring Boot and Hibernate application with the AWS Advanced JDBC Wrapper, and use the IAM Authentication plugin to fetch some data from an Aurora PostgreSQL database.

> Note: this tutorial was written using the following technologies:
> - Spring Boot 2.7.1
> - Hibernate
> - Spring Boot 3.4.4
> - Hibernate 6.x (via Spring Boot)
> - AWS Advanced JDBC Wrapper 3.2.0
> - Postgresql 42.5.4
> - Gradle 7
> - Java 11
> - Postgresql 42.7.10
> - Gradle 8
> - Java 17

You will progress through the following sections:
1. Create a Gradle Spring Boot project
Expand Down Expand Up @@ -62,9 +62,9 @@ public class SpringHibernateExampleApplication implements CommandLineRunner {
```java
package example.data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Example {
Expand Down Expand Up @@ -157,7 +157,7 @@ spring:
exception-override-class-name: software.amazon.jdbc.util.HikariCPSQLException
max-lifetime: 1260000
```
Since Spring 2+ uses Hikari to manage datasources, to configure the driver we would need to specify the `data-source-properties` under `hikari`.
Since Spring Boot 3+ uses Hikari to manage datasources, to configure the driver we would need to specify the `data-source-properties` under `hikari`.
Whenever Hikari is used, we also need to ensure failover exceptions are handled correctly so connections will not be discarded from the pool after failover has occurred. This can be done by overriding the exception handling class. For more information on this, please see [the documentation on HikariCP](../../docs/using-the-jdbc-driver/using-plugins/UsingTheFailoverPlugin.md#hikaricp).

This example contains some very simple configurations for the IAM Authentication plugin, if you are interested in other configurations related to failover, please visit [the documentation for failover parameters](../../docs/using-the-jdbc-driver/using-plugins/UsingTheFailoverPlugin.md#failover-parameters)
Expand Down
12 changes: 9 additions & 3 deletions examples/SpringHibernateExample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@
*/

plugins {
id("org.springframework.boot") version "2.7.0"
id("org.springframework.boot") version "3.4.4"
id("io.spring.dependency-management") version "1.1.7"
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.postgresql:postgresql:42.7.7")
implementation("software.amazon.awssdk:rds:2.42.4")
implementation("org.postgresql:postgresql:42.7.10")
implementation("software.amazon.awssdk:rds:2.42.15")
implementation(project(":aws-advanced-jdbc-wrapper"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package example.data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Example {
Expand Down
22 changes: 16 additions & 6 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,40 @@ include(
"hikari",
"dbcp",
"driverexample",
"springhibernate",
"springhibernateonedatasource",
"springhibernatetwodatasource",
"springwildfly",
"springboothikariexample",
"springtxfailover",
"vertxexample",
"readwritesample"
)

// Submodules that require Java 17+
if (JavaVersion.current() >= JavaVersion.VERSION_17) {
include(
"springhibernate",
"springhibernateonedatasource",
"springhibernatetwodatasource"
)
}

project(":aws-advanced-jdbc-wrapper").projectDir = file("wrapper")
project(":hibernate").projectDir = file("examples/HibernateExample")
project(":hikari").projectDir = file("examples/HikariExample")
project(":dbcp").projectDir = file("examples/DBCPExample")
project(":driverexample").projectDir = file("examples/AWSDriverExample")
project(":springhibernate").projectDir = file("examples/SpringHibernateExample")
project(":springhibernateonedatasource").projectDir = file("examples/SpringHibernateBalancedReaderOneDataSourceExample")
project(":springhibernatetwodatasource").projectDir = file("examples/SpringHibernateBalancedReaderTwoDataSourceExample")
project(":springwildfly").projectDir = file("examples/SpringWildflyExample/spring")
project(":springboothikariexample").projectDir = file("examples/SpringBootHikariExample")
project(":springtxfailover").projectDir = file("examples/SpringTxFailoverExample")
project(":vertxexample").projectDir = file("examples/VertxExample")
project(":readwritesample").projectDir = file("examples/ReadWriteSplittingSample")

// Only include these submodules is the current configured Java version is greater or equal to Java 17
if (JavaVersion.current() >= JavaVersion.VERSION_17) {
project(":springhibernate").projectDir = file("examples/SpringHibernateExample")
project(":springhibernateonedatasource").projectDir = file("examples/SpringHibernateBalancedReaderOneDataSourceExample")
project(":springhibernatetwodatasource").projectDir = file("examples/SpringHibernateBalancedReaderTwoDataSourceExample")
}

pluginManagement {
plugins {
fun String.v() = extra["$this.version"].toString()
Expand Down
37 changes: 34 additions & 3 deletions wrapper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ dependencies {
testImplementation("org.apache.commons:commons-pool2:2.11.1")
testImplementation("org.jsoup:jsoup:1.21.1")
testImplementation("de.vandermeer:asciitable:0.3.2")
testImplementation("org.hibernate:hibernate-core:5.6.15.Final") // the latest version compatible with Java 8
testImplementation("jakarta.persistence:jakarta.persistence-api:2.2.3")
testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.2")
testImplementation("io.valkey:valkey-glide:2.3.0:$nativeClassifier") // Note: to run unit tests on ARM Mac, change native classifier to "osx-x86_64"
}
Expand Down Expand Up @@ -173,9 +171,33 @@ tasks.named<JavaCompile>(java24.compileJavaTaskName) {
dependsOn(tasks.compileJava)
}

// Hibernate v7.3 requires at least Java 17
// Create a source set for these tests and compile the Hibernate tests against Java 17
val hibernateTest = sourceSets.create("hibernateTest") {
java {
srcDir("src/test/java17")
}
// Include main output and test output (excluding Hibernate) for dependencies
val paths = sourceSets.main.get().output + sourceSets.test.get().output + sourceSets.test.get().compileClasspath
compileClasspath += paths
runtimeClasspath += paths
}

tasks.named<JavaCompile>(hibernateTest.compileJavaTaskName) {
javaCompiler.set(javaToolchains.compilerFor {
languageVersion.set(JavaLanguageVersion.of(17))
})
options.release.set(17)
// Ensure test classes are compiled before Hibernate test classes
dependsOn(tasks.compileTestJava)
}

dependencies {
add(java11.compileOnlyConfigurationName, "org.checkerframework:checker-qual:3.52.0")
add(java24.compileOnlyConfigurationName, "org.checkerframework:checker-qual:3.52.0")
// Hibernate test dependencies (Java 17+)
add(hibernateTest.implementationConfigurationName, "org.hibernate:hibernate-core:7.3.0.Final")
add(hibernateTest.implementationConfigurationName, "jakarta.persistence:jakarta.persistence-api:3.2.0")
}

fun CopySpec.addMultiReleaseContents() {
Expand Down Expand Up @@ -440,12 +462,17 @@ junitHtmlReport {

tasks.withType<Test> {
dependsOn("jar")
dependsOn(tasks.named(hibernateTest.compileJavaTaskName))
testLogging {
this.showStandardStreams = true
}
useJUnitPlatform()
outputs.upToDateWhen { false }

// Include hibernate test classes in the test classpath
testClassesDirs += hibernateTest.output.classesDirs
classpath += hibernateTest.output

System.getProperties().forEach {
if (it.key.toString().startsWith("test-no-")
|| it.key.toString() == "test-include-tags"
Expand Down Expand Up @@ -531,7 +558,11 @@ tasks.register<Test>("test-hibernate-only") {
systemProperty("test-no-mariadb-engine", "true")
systemProperty("test-no-openjdk8", "true")
systemProperty("test-no-openjdk11", "true")
systemProperty("test-no-openjdk17", "true")
// Test hibernate against Java 17+
systemProperty("test-no-openjdk17", "false")
systemProperty("test-no-openjdk21", "false")
systemProperty("test-no-openjdk22", "false")
systemProperty("test-no-openjdk24", "false")
systemProperty("test-no-graalvm", "true")
systemProperty("test-hibernate-only", "true")
systemProperty("test-no-bg", "true")
Expand Down
31 changes: 27 additions & 4 deletions wrapper/src/test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ dependencies {
testImplementation("io.opentelemetry:opentelemetry-sdk-metrics:1.43.0")
testImplementation("io.opentelemetry:opentelemetry-exporter-otlp:1.44.1")
testImplementation("de.vandermeer:asciitable:0.3.2")
testImplementation("org.hibernate:hibernate-core:5.6.15.Final") // the latest version compatible with Java 8
testImplementation("jakarta.persistence:jakarta.persistence-api:2.2.3")
testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.2")
val arch = System.getProperty("os.arch").let {
when (it) {
Expand All @@ -82,10 +80,35 @@ dependencies {
testImplementation("io.valkey:valkey-glide:2.3.0:$glideClassifier")
}

// Hibernate v7.3 requires at least Java 17
// Create a separate source set for Hibernate tests compiled with Java 17
val hibernateTest: SourceSet by sourceSets.creating {
java {
srcDir("java17")
}
compileClasspath += sourceSets.test.get().output + sourceSets.test.get().compileClasspath
runtimeClasspath += sourceSets.test.get().output + sourceSets.test.get().runtimeClasspath
}

tasks.named<JavaCompile>(hibernateTest.compileJavaTaskName) {
javaCompiler.set(javaToolchains.compilerFor {
languageVersion.set(JavaLanguageVersion.of(17))
})
options.release.set(17)
dependsOn(tasks.compileTestJava)
}

dependencies {
// Hibernate test dependencies (Java 17+)
add(hibernateTest.implementationConfigurationName, "org.hibernate:hibernate-core:7.3.0.Final")
add(hibernateTest.implementationConfigurationName, "jakarta.persistence:jakarta.persistence-api:3.2.0")
}

tasks.withType<Test> {
dependsOn(tasks.named(hibernateTest.compileJavaTaskName))

testClassesDirs += fileTree("./libs") { include("*.jar") } + project.files("./test")
classpath += fileTree("./libs") { include("*.jar") } + project.files("./test")
testClassesDirs += fileTree("./libs") { include("*.jar") } + project.files("./test") + hibernateTest.output.classesDirs
classpath += fileTree("./libs") { include("*.jar") } + project.files("./test") + hibernateTest.output
outputs.upToDateWhen { false }

useJUnitPlatform {
Expand Down
Loading
Loading