@@ -158,8 +158,8 @@ public class SessionImpl
158158 implements Serializable , SharedSessionContractImplementor , JdbcSessionOwner , SessionImplementor , EventSource ,
159159 TransactionCoordinatorBuilder .Options , WrapperOptions , LoadAccessContext {
160160
161- // Defaults to null which means the properties are the default
162- // as defined in FastSessionServices#defaultSessionProperties
161+ // Defaults to null, meaning the properties
162+ // are the default properties of the factory.
163163 private Map <String , Object > properties ;
164164
165165 private transient ActionQueue actionQueue ;
@@ -191,8 +191,6 @@ public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
191191 actionQueue = createActionQueue ();
192192 eventListenerGroups = factory .getEventListenerGroups ();
193193
194- flushMode = options .getInitialSessionFlushMode ();
195-
196194 autoClear = options .shouldAutoClear ();
197195 autoClose = options .shouldAutoClose ();
198196
@@ -202,13 +200,10 @@ public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
202200
203201 loadQueryInfluencers = new LoadQueryInfluencers ( factory , options );
204202
205- // NOTE : pulse() already handles auto-join-ability correctly
203+ // NOTE: pulse() already handles auto-join-ability correctly
206204 getTransactionCoordinator ().pulse ();
207205
208- // do not override explicitly set flush mode ( SessionBuilder#flushMode() )
209- if ( getHibernateFlushMode () == null ) {
210- setHibernateFlushMode ( getInitialFlushMode () );
211- }
206+ flushMode = getInitialFlushMode ( options );
212207
213208 setUpMultitenancy ( factory , loadQueryInfluencers );
214209
@@ -247,10 +242,16 @@ private static void setUpTransactionCompletionProcesses(
247242 }
248243 }
249244
250- private FlushMode getInitialFlushMode () {
251- return properties == null
252- ? getSessionFactoryOptions ().getInitialSessionFlushMode ()
253- : ConfigurationHelper .getFlushMode ( getSessionProperty ( HINT_FLUSH_MODE ), FlushMode .AUTO );
245+ private FlushMode getInitialFlushMode (SessionCreationOptions options ) {
246+ final var initialSessionFlushMode = options .getInitialSessionFlushMode ();
247+ if ( initialSessionFlushMode != null ) {
248+ return initialSessionFlushMode ;
249+ }
250+ else {
251+ return properties == null
252+ ? getSessionFactoryOptions ().getInitialSessionFlushMode ()
253+ : ConfigurationHelper .getFlushMode ( properties .get ( HINT_FLUSH_MODE ), FlushMode .AUTO );
254+ }
254255 }
255256
256257 protected PersistenceContext createPersistenceContext (SessionCreationOptions options ) {
@@ -351,7 +352,6 @@ public void clear() {
351352 private void internalClear () {
352353 persistenceContext .clear ();
353354 actionQueue .clear ();
354-
355355 eventListenerGroups .eventListenerGroup_CLEAR
356356 .fireLazyEventOnEachListener ( this ::createClearEvent , ClearEventListener ::onClear );
357357 }
@@ -392,7 +392,7 @@ public void closeWithoutOpenChecks() {
392392 else {
393393 // In the JPA bootstrap, if the session is closed
394394 // before the transaction commits, we just mark the
395- // session as closed, and set waitingForAutoClose.
395+ // session as closed and set waitingForAutoClose.
396396 // This method will be called a second time from
397397 // afterTransactionCompletion when the transaction
398398 // commits, and the session will be closed for real.
@@ -405,10 +405,12 @@ public void closeWithoutOpenChecks() {
405405 }
406406 }
407407 finally {
408- // E.g. when we are in the JTA context the session can get closed while the transaction is still active
409- // and JTA will call the AfterCompletion itself. Hence, we don't want to clear out the action queue callbacks at this point:
410- if ( !getTransactionCoordinator ().isTransactionActive () && actionQueue .hasAfterTransactionActions () ) {
411- SESSION_LOGGER .warn ( "Closing session with unprocessed clean up bulk operations, forcing their execution" );
408+ // E.g. When we are in the JTA context, the session can get closed while the
409+ // transaction is still active and JTA will call the AfterCompletion itself.
410+ // Hence, we don't want to clear out the action queue callbacks at this point:
411+ if ( !getTransactionCoordinator ().isTransactionActive ()
412+ && actionQueue .hasAfterTransactionActions () ) {
413+ SESSION_LOGGER .closingSessionWithUnprocessedBulkOperations ();
412414 actionQueue .executePendingBulkOperationCleanUpActions ();
413415 }
414416 final var statistics = getSessionFactory ().getStatistics ();
@@ -489,8 +491,8 @@ else if ( isClosed() ) {
489491 return false ;
490492 }
491493 else {
492- // JPA technically requires that this be a PersistentUnityTransactionType# JTA to work ,
493- // but we do not assert that here:
494+ // JPA requires PersistentUnitTransactionType. JTA,
495+ // for this, but we do not assert that here:
494496 return isAutoCloseSessionEnabled ();
495497 // && getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
496498 }
@@ -557,7 +559,9 @@ public Object getEntityUsingInterceptor(EntityKey key) {
557559 // logically, is PersistentContext the "thing" to which an interceptor gets attached?
558560 final Object result = persistenceContext .getEntity ( key );
559561 if ( result == null ) {
560- final Object newObject = getInterceptor ().getEntity ( key .getEntityName (), key .getIdentifier () );
562+ final Object newObject =
563+ getInterceptor ()
564+ .getEntity ( key .getEntityName (), key .getIdentifier () );
561565 if ( newObject != null ) {
562566 lock ( newObject , LockMode .NONE );
563567 }
@@ -870,8 +874,8 @@ public void removeOrphanBeforeUpdates(String entityName, Object child) {
870874 private void logRemoveOrphanBeforeUpdates (String timing , String entityName , Object entity ) {
871875 if ( SESSION_LOGGER .isTraceEnabled () ) {
872876 final var entityEntry = persistenceContext .getEntry ( entity );
873- final String entityInfo = entityEntry == null ? entityName : infoString ( entityName , entityEntry . getId () );
874- SESSION_LOGGER . removeOrphanBeforeUpdates ( timing , entityInfo );
877+ SESSION_LOGGER . removeOrphanBeforeUpdates ( timing ,
878+ entityEntry == null ? entityName : infoString ( entityName , entityEntry . getId () ) );
875879 }
876880 }
877881
@@ -933,7 +937,7 @@ private <T> void setMultiIdentifierLoadAccessOptions(FindOption[] options, Multi
933937 CacheRetrieveMode retrieveMode = getCacheRetrieveMode ();
934938 LockOptions lockOptions = copySessionLockOptions ();
935939 int batchSize = -1 ;
936- for ( FindOption option : options ) {
940+ for ( var option : options ) {
937941 if ( option instanceof CacheStoreMode cacheStoreMode ) {
938942 storeMode = cacheStoreMode ;
939943 }
@@ -1553,7 +1557,8 @@ public void forceFlush(EntityEntry entityEntry) {
15531557 @ Override
15541558 public void forceFlush (EntityKey key ) {
15551559 if ( SESSION_LOGGER .isTraceEnabled () ) {
1556- SESSION_LOGGER .flushingToForceDeletion ( infoString ( key .getPersister (), key .getIdentifier (), getFactory () ) );
1560+ SESSION_LOGGER .flushingToForceDeletion (
1561+ infoString ( key .getPersister (), key .getIdentifier (), getFactory () ) );
15571562 }
15581563
15591564 if ( persistenceContext .getCascadeLevel () > 0 ) {
@@ -2124,7 +2129,7 @@ private boolean isTransactionFlushable() {
21242129 return true ;
21252130 }
21262131 else {
2127- final TransactionStatus status = currentTransaction .getStatus ();
2132+ final var status = currentTransaction .getStatus ();
21282133 return status == TransactionStatus .ACTIVE
21292134 || status == TransactionStatus .COMMITTING ;
21302135 }
@@ -2190,13 +2195,13 @@ private <T> T find(Class<T> entityClass, Object primaryKey, LockOptions lockOpti
21902195 .load ( primaryKey );
21912196 }
21922197 catch ( FetchNotFoundException e ) {
2193- // This may happen if the entity has an associations mapped with
2198+ // This may happen if the entity has an association mapped with
21942199 // @NotFound(action = NotFoundAction.EXCEPTION) and this associated
21952200 // entity is not found
21962201 throw e ;
21972202 }
21982203 catch ( EntityFilterException e ) {
2199- // This may happen if the entity has an associations which is
2204+ // This may happen if the entity has an association which is
22002205 // filtered by a FilterDef and this associated entity is not found
22012206 throw e ;
22022207 }
@@ -2256,7 +2261,7 @@ private <T> void setLoadAccessOptions(FindOption[] options, IdentifierLoadAccess
22562261 CacheStoreMode storeMode = getCacheStoreMode ();
22572262 CacheRetrieveMode retrieveMode = getCacheRetrieveMode ();
22582263 LockOptions lockOptions = copySessionLockOptions ();
2259- for ( FindOption option : options ) {
2264+ for ( var option : options ) {
22602265 if ( option instanceof CacheStoreMode cacheStoreMode ) {
22612266 storeMode = cacheStoreMode ;
22622267 }
@@ -2295,15 +2300,15 @@ else if ( option instanceof ReadOnlyMode ) {
22952300 loadAccess .withReadOnly ( option == ReadOnlyMode .READ_ONLY );
22962301 }
22972302 else if ( option instanceof FindMultipleOption findMultipleOption ) {
2298- throw new IllegalArgumentException ( "Option '" + findMultipleOption + "' can only be used in 'findMultiple()'" );
2303+ throw new IllegalArgumentException ( "Option '" + findMultipleOption
2304+ + "' can only be used in 'findMultiple()'" );
22992305 }
23002306 }
2301- if ( lockOptions .getLockMode ().isPessimistic () ) {
2302- if ( lockOptions .getTimeOut () == WAIT_FOREVER_MILLI ) {
2303- final Object factoryHint = getFactory ().getProperties ().get ( HINT_SPEC_LOCK_TIMEOUT );
2304- if ( factoryHint != null ) {
2305- lockOptions .setTimeOut ( Timeouts .fromHint ( factoryHint ) );
2306- }
2307+ if ( lockOptions .getLockMode ().isPessimistic ()
2308+ && lockOptions .getTimeOut () == WAIT_FOREVER_MILLI ) {
2309+ final Object factoryHint = getFactory ().getProperties ().get ( HINT_SPEC_LOCK_TIMEOUT );
2310+ if ( factoryHint != null ) {
2311+ lockOptions .setTimeOut ( Timeouts .fromHint ( factoryHint ) );
23072312 }
23082313 }
23092314 loadAccess .with ( lockOptions ).with ( interpretCacheMode ( storeMode , retrieveMode ) );
@@ -2578,25 +2583,23 @@ public LockModeType getLockMode(Object entity) {
25782583 @ Override
25792584 public void setProperty (String propertyName , Object value ) {
25802585 checkOpen ();
2581-
2582- if ( !( value instanceof Serializable ) ) {
2583- SESSION_LOGGER .nonSerializableProperty ( propertyName );
2584- return ;
2585- }
2586-
2587- if ( propertyName == null ) {
2588- SESSION_LOGGER .nullPropertyKey ();
2589- return ;
2586+ if ( value instanceof Serializable ) {
2587+ if ( propertyName != null ) { // store property for future reference:
2588+ if ( properties == null ) {
2589+ properties = computeCurrentProperties ();
2590+ }
2591+ properties .put ( propertyName , value );
2592+ // now actually update the setting
2593+ // if it's one that affects this Session
2594+ interpretProperty ( propertyName , value );
2595+ }
2596+ else {
2597+ SESSION_LOGGER .nullPropertyKey ();
2598+ }
25902599 }
2591-
2592- // store property for future reference:
2593- if ( properties == null ) {
2594- properties = computeCurrentProperties ();
2600+ else {
2601+ SESSION_LOGGER .nonSerializableProperty ( propertyName );
25952602 }
2596- properties .put ( propertyName , value );
2597-
2598- // now actually update the setting, if it's one which affects this Session
2599- interpretProperty ( propertyName , value );
26002603 }
26012604
26022605 private void interpretProperty (String propertyName , Object value ) {
0 commit comments