diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fbc73fcb5..2bd93c7b7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,6 +19,7 @@ updates: - package-ecosystem: "gradle" directory: "/" + target-branch: "main" schedule: interval: "weekly" day: "tuesday" @@ -48,11 +49,166 @@ updates: - "com.fasterxml.jackson.core*" - "com.mysql*" - "org.mariadb.jdbc*" + ignore: + # For Hibernate Validator, we will need to update major version manually as needed (but we only use it in tests) + - dependency-name: "org.glassfish.expressly*" + update-types: ["version-update:semver-major"] + # Only patches for Hibernate ORM and Vert.x + - dependency-name: "org.hibernate*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + - dependency-name: "io.vertx*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + + # Dockerfiles in tooling/docker/, and database services we use for examples (MySQL and PostgreSQL) + - package-ecosystem: "docker" + directory: "/tooling/docker" + target-branch: "main" + schedule: + interval: "weekly" + allow: + - dependency-type: "all" + - package-ecosystem: "gradle" + directory: "/" + target-branch: "main" + schedule: + interval: "weekly" + day: "tuesday" + open-pull-requests-limit: 20 + groups: + hibernate-validator: + patterns: + - "org.hibernate.validator*" + - "org.glassfish.expressly*" + hibernate: + patterns: + - "org.hibernate*" + vertx: + patterns: + - "io.vertx*" + mutiny: + patterns: + - "io.smallrye.reactive*" + # Testcontainers plus the JDBC driver we need for testing + testcontainers: + patterns: + - "org.testcontainers*" + - "com.ibm.db2*" + - "com.microsoft.sqlserver*" + - "org.postgresql*" + - "con.ongres.scram*" + - "com.fasterxml.jackson.core*" + - "com.mysql*" + - "org.mariadb.jdbc*" + ignore: + # For Hibernate Validator, we will need to update major version manually as needed (but we only use it in tests) + - dependency-name: "org.glassfish.expressly*" + update-types: ["version-update:semver-major"] + # Only patches for Hibernate ORM and Vert.x + - dependency-name: "org.hibernate*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + - dependency-name: "io.vertx*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + + # Dockerfiles in tooling/docker/, and database services we use for examples (MySQL and PostgreSQL) + - package-ecosystem: "docker" + directory: "/tooling/docker" + target-branch: "main" + schedule: + interval: "weekly" + allow: + - dependency-type: "all" + +################################################################################# +# Duplicate the package-ecosystems for main because we want to target branch 3.1 +# and dependabot doesn't support YAML aliases and anchors at the moment +################################################################################# + - package-ecosystem: "gradle" + directory: "/" + target-branch: "3.1" + schedule: + interval: "weekly" + day: "tuesday" + open-pull-requests-limit: 20 + groups: + hibernate-validator: + patterns: + - "org.hibernate.validator*" + - "org.glassfish.expressly*" + hibernate: + patterns: + - "org.hibernate*" + vertx: + patterns: + - "io.vertx*" + mutiny: + patterns: + - "io.smallrye.reactive*" + testcontainers: + patterns: + - "org.testcontainers*" + - "com.ibm.db2*" + - "com.microsoft.sqlserver*" + - "org.postgresql*" + - "con.ongres.scram*" + - "com.fasterxml.jackson.core*" + - "com.mysql*" + - "org.mariadb.jdbc*" + ignore: + - dependency-name: "org.glassfish.expressly*" + update-types: ["version-update:semver-major"] + - dependency-name: "org.hibernate*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + - dependency-name: "io.vertx*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + - package-ecosystem: "docker" + directory: "/tooling/docker" + target-branch: "3.1" + schedule: + interval: "weekly" + allow: + - dependency-type: "all" + + ################################################################################# + # Duplicate the package-ecosystems for main because we want to target branch 2.4 + # and dependabot doesn't support YAML aliases and anchors at the moment + ################################################################################# + - package-ecosystem: "gradle" + directory: "/" + target-branch: "2.4" + schedule: + interval: "weekly" + day: "tuesday" + open-pull-requests-limit: 20 + groups: + hibernate-validator: + patterns: + - "org.hibernate.validator*" + - "org.glassfish.expressly*" + hibernate: + patterns: + - "org.hibernate*" + vertx: + patterns: + - "io.vertx*" + mutiny: + patterns: + - "io.smallrye.reactive*" + # Testcontainers plus the JDBC driver we need for testing + testcontainers: + patterns: + - "org.testcontainers*" + - "com.ibm.db2*" + - "com.microsoft.sqlserver*" + - "org.postgresql*" + - "con.ongres.scram*" + - "com.fasterxml.jackson.core*" + - "com.mysql*" + - "org.mariadb.jdbc*" ignore: # For Hibernate Validator, we will need to update major version manually as needed (but we only use it in tests) - dependency-name: "org.glassfish.expressly*" - update-types: ["version-update-:semver-major"] + update-types: ["version-update:semver-major"] # Only patches for Hibernate ORM and Vert.x - dependency-name: "org.hibernate*" update-types: ["version-update:semver-major", "version-update:semver-minor"] @@ -62,6 +218,7 @@ updates: # Dockerfiles in tooling/docker/, and database services we use for examples (MySQL and PostgreSQL) - package-ecosystem: "docker" directory: "/tooling/docker" + target-branch: "main" schedule: interval: "weekly" allow: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e1f766dc..f17ca55a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,7 +83,7 @@ jobs: - 5432:5432 steps: - name: Checkout ${{ inputs.branch }} - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ inputs.branch }} - name: Get year/month for cache key @@ -92,7 +92,7 @@ jobs: echo "::set-output name=yearmonth::$(/bin/date -u "+%Y-%m")" shell: bash - name: Cache Gradle downloads - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache-gradle with: path: | @@ -132,7 +132,7 @@ jobs: db: [ 'MariaDB', 'MySQL', 'PostgreSQL', 'MSSQLServer', 'CockroachDB', 'Db2', 'Oracle' ] steps: - name: Checkout ${{ inputs.branch }} - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ inputs.branch }} - name: Get year/month for cache key @@ -141,7 +141,7 @@ jobs: echo "::set-output name=yearmonth::$(/bin/date -u "+%Y-%m")" shell: bash - name: Cache Gradle downloads - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache-gradle with: path: | @@ -198,7 +198,7 @@ jobs: - { name: "26-ea", java_version_numeric: 26, from: 'jdk.java.net', jvm_args: '--enable-preview' } steps: - name: Checkout ${{ inputs.branch }} - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ inputs.branch }} - name: Get year/month for cache key @@ -219,7 +219,7 @@ jobs: echo "buildtool-cache-key=${ROOT_CACHE_KEY}-${CURRENT_MONTH}-${CURRENT_BRANCH}-${CURRENT_DAY}" >> $GITHUB_OUTPUT - name: Cache Maven/Gradle Dependency/Dist Caches id: cache-maven - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 # if it's not a pull request, we restore and save the cache if: github.event_name != 'pull_request' with: @@ -236,7 +236,7 @@ jobs: ${{ steps.cache-key.outputs.buildtool-monthly-branch-cache-key }}- ${{ steps.cache-key.outputs.buildtool-monthly-cache-key }}- - name: Restore Maven/Gradle Dependency/Dist Caches - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 # if it's a pull request, we restore the cache, but we don't save it if: github.event_name == 'pull_request' with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ce053481f..99db067a3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Java uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 diff --git a/.github/workflows/scheduler.yml b/.github/workflows/scheduler.yml index 57a1c58fc..535d14f67 100644 --- a/.github/workflows/scheduler.yml +++ b/.github/workflows/scheduler.yml @@ -10,6 +10,7 @@ on: jobs: build-snapshots: strategy: + fail-fast: false matrix: branch: [ 'wip/2.4', 'wip/3.0', 'wip/3.1', 'wip/4.0', 'wip/4.1' ] uses: ./.github/workflows/build.yml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5f6355381..030797ff5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -assertjVersion = "3.27.3" +assertjVersion = "3.27.4" hibernateOrmVersion = "7.1.0.Final" hibernateOrmGradlePluginVersion = "7.1.0.Final" jacksonDatabindVersion = "2.19.2" @@ -9,14 +9,14 @@ junitVersion = "5.13.4" junitPlatformVersion = "1.13.3" log4jVersion = "2.25.1" testcontainersVersion = "1.21.3" -vertxSqlClientVersion = "5.0.2" -vertxWebVersion= "5.0.2" -vertxWebClientVersion = "5.0.2" +vertxSqlClientVersion = "5.0.3" +vertxWebVersion= "5.0.3" +vertxWebClientVersion = "5.0.3" [libraries] com-fasterxml-jackson-core-jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind", version.ref = "jacksonDatabindVersion" } com-ibm-db2-jcc = { group = "com.ibm.db2", name = "jcc", version = "12.1.2.0" } -com-microsoft-sqlserver-mssql-jdbc = { group = "com.microsoft.sqlserver", name = "mssql-jdbc", version = "13.1.1.jre11-preview" } +com-microsoft-sqlserver-mssql-jdbc = { group = "com.microsoft.sqlserver", name = "mssql-jdbc", version = "13.2.0.jre11" } com-mysql-mysql-connector-j = { group = "com.mysql", name = "mysql-connector-j", version = "9.4.0" } com-ongres-scram-scram-client = { group = "com.ongres.scram", name = "scram-client", version = "3.1" } io-smallrye-reactive-mutiny = { group = "io.smallrye.reactive", name = "mutiny", version = "2.9.4" } @@ -32,19 +32,19 @@ io-vertx-vertx-web = { group = "io.vertx", name = "vertx-web", version.ref = "ve io-vertx-vertx-web-client = { group = "io.vertx", name = "vertx-web-client", version.ref = "vertxWebClientVersion" } org-apache-logging-log4j-log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4jVersion" } org-assertj-assertj-core = { group = "org.assertj", name = "assertj-core", version.ref = "assertjVersion" } -org-ehcache-ehcache = { group = "org.ehcache", name = "ehcache", version = "3.10.8" } +org-ehcache-ehcache = { group = "org.ehcache", name = "ehcache", version = "3.11.0" } org-glassfish-expressly-expressly = { group = "org.glassfish.expressly", name = "expressly", version = "5.0.0" } org-hibernate-orm-hibernate-core = { group = "org.hibernate.orm", name = "hibernate-core", version.ref = "hibernateOrmVersion" } org-hibernate-orm-hibernate-jcache = { group = "org.hibernate.orm", name = "hibernate-jcache", version.ref = "hibernateOrmVersion" } org-hibernate-orm-hibernate-jpamodelgen = { group = "org.hibernate.orm", name = "hibernate-jpamodelgen", version.ref = "hibernateOrmVersion" } -org-hibernate-validator-hibernate-validator = { group = "org.hibernate.validator", name = "hibernate-validator", version = "8.0.2.Final" } +org-hibernate-validator-hibernate-validator = { group = "org.hibernate.validator", name = "hibernate-validator", version = "8.0.3.Final" } org-jboss-logging-jboss-logging = { group = "org.jboss.logging", name = "jboss-logging", version.ref = "jbossLoggingVersion" } org-jboss-logging-jboss-logging-annotations = { group = "org.jboss.logging", name = "jboss-logging-annotations", version.ref = "jbossLoggingAnnotationVersion" } org-jboss-logging-jboss-logging-processor = { group = "org.jboss.logging", name = "jboss-logging-processor", version.ref = "jbossLoggingAnnotationVersion" } org-junit-jupiter-junit-jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junitVersion" } org-junit-jupiter-junit-jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junitVersion" } org-junit-platform-junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version = "1.13.4" } -org-mariadb-jdbc-mariadb-java-client = { group = "org.mariadb.jdbc", name = "mariadb-java-client", version = "3.5.4" } +org-mariadb-jdbc-mariadb-java-client = { group = "org.mariadb.jdbc", name = "mariadb-java-client", version = "3.5.5" } org-postgresql-postgresql = { group = "org.postgresql", name = "postgresql", version = "42.7.7" } org-testcontainers-cockroachdb = { group = "org.testcontainers", name = "cockroachdb", version.ref = "testcontainersVersion" } org-testcontainers-db2 = { group = "org.testcontainers", name = "db2", version.ref = "testcontainersVersion" } diff --git a/gradle/version.properties b/gradle/version.properties index 5788ca34e..d879dfd09 100644 --- a/gradle/version.properties +++ b/gradle/version.properties @@ -1 +1 @@ -projectVersion=4.1.0.Final \ No newline at end of file +projectVersion=4.1.1-SNAPSHOT \ No newline at end of file diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java index 508625bcb..223b46fc0 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/BaseReactiveTest.java @@ -293,38 +293,32 @@ protected CompletionStage cleanDb() { } protected static CompletionStage closeSession(Object closable) { - if ( closable instanceof CompletionStage ) { - CompletionStage closableStage = (CompletionStage) closable; + if ( closable instanceof CompletionStage closableStage ) { return closableStage.thenCompose( BaseReactiveTest::closeSession ); } - if ( closable instanceof Uni ) { - Uni closableUni = (Uni) closable; + if ( closable instanceof Uni closableUni ) { return closableUni.subscribeAsCompletionStage() .thenCompose( BaseReactiveTest::closeSession ); } - if ( closable instanceof ReactiveConnection ) { - return ( (ReactiveConnection) closable ).close(); + if ( closable instanceof ReactiveConnection reactiveConnection) { + return reactiveConnection.close(); } - if ( closable instanceof Mutiny.Session ) { - Mutiny.Session mutiny = (Mutiny.Session) closable; + if ( closable instanceof Mutiny.Session mutiny ) { if ( mutiny.isOpen() ) { return mutiny.close().subscribeAsCompletionStage(); } } - if ( closable instanceof Stage.Session ) { - Stage.Session stage = (Stage.Session) closable; + if ( closable instanceof Stage.Session stage ) { if ( stage.isOpen() ) { return stage.close(); } } - if ( closable instanceof Mutiny.StatelessSession ) { - Mutiny.StatelessSession mutiny = (Mutiny.StatelessSession) closable; + if ( closable instanceof Mutiny.StatelessSession mutiny ) { if ( mutiny.isOpen() ) { return mutiny.close().subscribeAsCompletionStage(); } } - if ( closable instanceof Stage.StatelessSession ) { - Stage.StatelessSession stage = (Stage.StatelessSession) closable; + if ( closable instanceof Stage.StatelessSession stage ) { if ( stage.isOpen() ) { return stage.close(); } diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CollectionStatelessSessionListenerTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CollectionStatelessSessionListenerTest.java new file mode 100644 index 000000000..0d88a6700 --- /dev/null +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/CollectionStatelessSessionListenerTest.java @@ -0,0 +1,245 @@ +/* Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.reactive; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.AbstractCollectionEvent; +import org.hibernate.event.spi.EventType; +import org.hibernate.event.spi.PostCollectionRecreateEvent; +import org.hibernate.event.spi.PostCollectionRecreateEventListener; +import org.hibernate.event.spi.PostCollectionRemoveEvent; +import org.hibernate.event.spi.PostCollectionRemoveEventListener; +import org.hibernate.event.spi.PreCollectionRecreateEvent; +import org.hibernate.event.spi.PreCollectionRecreateEventListener; +import org.hibernate.event.spi.PreCollectionRemoveEvent; +import org.hibernate.event.spi.PreCollectionRemoveEventListener; + +import org.junit.jupiter.api.Test; + +import io.vertx.junit5.VertxTestContext; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Adapt test in ORM: CollectionStatelessSessionListenerTest + */ +public class CollectionStatelessSessionListenerTest extends BaseReactiveTest { + + @Override + protected Collection> annotatedEntities() { + return Set.of( EntityA.class, EntityB.class ); + } + + @Test + public void mutinyStatelessInsert(VertxTestContext context) { + final List events = new ArrayList<>(); + initializeListeners( events ); + + EntityA a = new EntityA(); + EntityB b = new EntityB(); + a.children.add( b ); + test( context, getMutinySessionFactory() + .withStatelessTransaction( statelessSession -> statelessSession + .insert( b ) + .chain( () -> statelessSession.insert( a ) ) + .chain( () -> statelessSession.delete( a ) ) + .chain( () -> statelessSession.delete( b ) ) + ) + .invoke( () -> assertEvents( events ) ) + ); + } + + @Test + public void mutinyStatelessInsertAll(VertxTestContext context) { + final List events = new ArrayList<>(); + initializeListeners( events ); + + EntityA a = new EntityA(); + EntityB b = new EntityB(); + a.children.add( b ); + test( context, getMutinySessionFactory() + .withStatelessTransaction( statelessSession -> statelessSession + .insertAll( b, a ) + .chain( () -> statelessSession.deleteAll( a, b ) ) + ) + .invoke( () -> assertEvents( events ) ) + ); + } + + @Test + public void stageStatelessInsert(VertxTestContext context) { + final List events = new ArrayList<>(); + initializeListeners( events ); + + EntityA a = new EntityA(); + EntityB b = new EntityB(); + a.children.add( b ); + test( context, getSessionFactory() + .withStatelessTransaction( statelessSession -> statelessSession + .insert( b ) + .thenCompose( v -> statelessSession.insert( a ) ) + .thenCompose( v -> statelessSession.delete( a ) ) + .thenCompose( v -> statelessSession.delete( b ) ) + ) + .thenAccept( v -> assertEvents( events ) ) + ); + } + + @Test + public void stageStatelessInsertAll(VertxTestContext context) { + final List events = new ArrayList<>(); + initializeListeners( events ); + + EntityA a = new EntityA(); + EntityB b = new EntityB(); + a.children.add( b ); + test( context, getSessionFactory() + .withStatelessTransaction( statelessSession -> statelessSession + .insert( b, a ) + .thenCompose( v -> statelessSession.delete( a, b ) ) + ) + .thenAccept( v -> assertEvents( events ) ) + ); + } + + private static void assertEvents(List events) { + assertThat( events ).hasSize( 4 ); + assertThat( events.get( 0 ) ) + .isInstanceOf( PreCollectionRecreateEvent.class ) + .extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() ); + assertThat( events.get( 1 ) ) + .isInstanceOf( PostCollectionRecreateEvent.class ) + .extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() ); + assertThat( events.get( 2 ) ) + .isInstanceOf( PreCollectionRemoveEvent.class ) + .extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() ); + assertThat( events.get( 3 ) ) + .isInstanceOf( PostCollectionRemoveEvent.class ) + .extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() ); + } + + private void initializeListeners(List events) { + final EventListenerRegistry registry = ( (SessionFactoryImplementor) factoryManager + .getHibernateSessionFactory() ) + .getEventListenerRegistry(); + + // Clear previous listeners + registry.getEventListenerGroup( EventType.PRE_COLLECTION_RECREATE ) + .clearListeners(); + registry.getEventListenerGroup( EventType.PRE_COLLECTION_REMOVE ) + .clearListeners(); + registry.getEventListenerGroup( EventType.POST_COLLECTION_RECREATE ) + .clearListeners(); + registry.getEventListenerGroup( EventType.POST_COLLECTION_REMOVE ) + .clearListeners(); + + // Add new listeners + registry.getEventListenerGroup( EventType.PRE_COLLECTION_RECREATE ) + .appendListener( new MyPreCollectionRecreateEventListener( events ) ); + registry.getEventListenerGroup( EventType.PRE_COLLECTION_REMOVE ) + .appendListener( new MyPreCollectionRemoveEventListener( events ) ); + registry.getEventListenerGroup( EventType.POST_COLLECTION_RECREATE ) + .appendListener( new MyPostCollectionRecreateEventListener( events ) ); + registry.getEventListenerGroup( EventType.POST_COLLECTION_REMOVE ) + .appendListener( new MyPostCollectionRemoveEventListener( events ) ); + } + + @Entity + @Table(name = "ENTITY_A") + public static class EntityA { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "ID") + Integer id; + + @OneToMany + @JoinColumn(name = "ENTITY_A") + Collection children = new ArrayList<>(); + } + + @Entity + @Table(name = "ENTITY_B") + public static class EntityB { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "ID") + Integer id; + } + + public static class MyPreCollectionRecreateEventListener implements PreCollectionRecreateEventListener { + + private final List events; + + + public MyPreCollectionRecreateEventListener(List events) { + this.events = events; + } + + @Override + public void onPreRecreateCollection(PreCollectionRecreateEvent event) { + events.add( event ); + } + + } + + public static class MyPreCollectionRemoveEventListener implements PreCollectionRemoveEventListener { + + private final List events; + + public MyPreCollectionRemoveEventListener(List events) { + this.events = events; + } + + @Override + public void onPreRemoveCollection(PreCollectionRemoveEvent event) { + events.add( event ); + } + + } + + public static class MyPostCollectionRecreateEventListener implements PostCollectionRecreateEventListener { + + private final List events; + + public MyPostCollectionRecreateEventListener(List events) { + this.events = events; + } + + @Override + public void onPostRecreateCollection(PostCollectionRecreateEvent event) { + events.add( event ); + } + } + + public static class MyPostCollectionRemoveEventListener implements PostCollectionRemoveEventListener { + + private final List events; + + public MyPostCollectionRemoveEventListener(List events) { + this.events = events; + } + + @Override + public void onPostRemoveCollection(PostCollectionRemoveEvent event) { + events.add( event ); + } + } +} diff --git a/tooling/docker/maria.Dockerfile b/tooling/docker/maria.Dockerfile index fc954df6e..6aa9bf898 100644 --- a/tooling/docker/maria.Dockerfile +++ b/tooling/docker/maria.Dockerfile @@ -1,3 +1,3 @@ # MariaDB # See https://hub.docker.com/_/mariadb -FROM docker.io/mariadb:11.8.2 +FROM docker.io/mariadb:12.0.2 diff --git a/tooling/docker/postgresql.Dockerfile b/tooling/docker/postgresql.Dockerfile index fb36f48e8..d245286dc 100644 --- a/tooling/docker/postgresql.Dockerfile +++ b/tooling/docker/postgresql.Dockerfile @@ -1,3 +1,3 @@ # PostgreSQL # See https://hub.docker.com/_/postgres -FROM docker.io/postgres:17.5 +FROM docker.io/postgres:17.6