From 3e17be98324a2aed8d18aab573c11a846e40c106 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Sun, 11 Aug 2019 21:50:15 +0100 Subject: [PATCH] HHH-13562 List of TransactionObserver for JdbcResourceLocalTransactionCoordinatorImpl should be lazily initialized --- ...esourceLocalTransactionCoordinatorImpl.java | 18 ++++++++++++++---- .../SessionWithSharedConnectionTest.java | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java index 1bbde93579..a637c01c19 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java @@ -7,6 +7,7 @@ package org.hibernate.resource.transaction.backend.jdbc.internal; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.persistence.RollbackException; import javax.transaction.Status; @@ -50,7 +51,7 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC private int timeOut = -1; - private final transient List observers; + private transient List observers = null; /** * Construct a ResourceLocalTransactionCoordinatorImpl instance. package-protected to ensure access goes through @@ -62,7 +63,6 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC TransactionCoordinatorBuilder transactionCoordinatorBuilder, TransactionCoordinatorOwner owner, JdbcResourceTransactionAccess jdbcResourceTransactionAccess) { - this.observers = new ArrayList<>(); this.transactionCoordinatorBuilder = transactionCoordinatorBuilder; this.jdbcResourceTransactionAccess = jdbcResourceTransactionAccess; this.transactionCoordinatorOwner = owner; @@ -81,7 +81,12 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC * @return TransactionObserver */ private Iterable observers() { - return new ArrayList<>( observers ); + if ( observers == null || observers.isEmpty() ) { + return Collections.emptyList(); + } + else { + return new ArrayList<>( observers ); + } } @Override @@ -203,12 +208,17 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC @Override public void addObserver(TransactionObserver observer) { + if ( observers == null ) { + observers = new ArrayList<>( 6 ); + } observers.add( observer ); } @Override public void removeObserver(TransactionObserver observer) { - observers.remove( observer ); + if ( observers != null ) { + observers.remove( observer ); + } } /** diff --git a/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java b/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java index 703174f6f8..ebec824f32 100644 --- a/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/sharedSession/SessionWithSharedConnectionTest.java @@ -270,7 +270,9 @@ public class SessionWithSharedConnectionTest extends BaseCoreFunctionalTestCase } assertNotNull("Observers field was not found", field); - assertEquals(0, ((Collection) field.get(((SessionImplementor) session).getTransactionCoordinator())).size()); + //Some of these collections could be lazily initialize: check for null before invoking size() + final Collection collection = (Collection) field.get( ( (SessionImplementor) session ).getTransactionCoordinator() ); + assertTrue(collection == null || collection.size() == 0 ); //open secondary sessions with managed options and immediately close Session secondarySession;