66
77import java .util .concurrent .CompletionStage ;
88
9+ import org .hibernate .DetachedObjectException ;
910import org .hibernate .HibernateException ;
1011import org .hibernate .LockMode ;
1112import org .hibernate .LockOptions ;
1213import org .hibernate .ObjectDeletedException ;
13- import org .hibernate .TransientObjectException ;
1414import org .hibernate .cache .spi .access .EntityDataAccess ;
1515import org .hibernate .cache .spi .access .SoftLock ;
16- import org .hibernate .engine .internal .CascadePoint ;
1716import org .hibernate .engine .spi .EntityEntry ;
1817import org .hibernate .engine .spi .PersistenceContext ;
1918import org .hibernate .engine .spi .SessionImplementor ;
2423import org .hibernate .event .spi .LockEventListener ;
2524import org .hibernate .persister .entity .EntityPersister ;
2625import org .hibernate .reactive .engine .ReactiveActionQueue ;
27- import org .hibernate .reactive .engine .impl .Cascade ;
28- import org .hibernate .reactive .engine .impl .CascadingActions ;
29- import org .hibernate .reactive .engine .impl .ForeignKeys ;
3026import org .hibernate .reactive .engine .impl .ReactiveEntityIncrementVersionProcess ;
3127import org .hibernate .reactive .engine .impl .ReactiveEntityVerifyVersionProcess ;
3228import org .hibernate .reactive .event .ReactiveLockEventListener ;
3834import static java .lang .invoke .MethodHandles .lookup ;
3935import static org .hibernate .pretty .MessageHelper .infoString ;
4036import static org .hibernate .reactive .logging .impl .LoggerFactory .make ;
41- import static org .hibernate .reactive .util .impl .CompletionStages .completedFuture ;
42- import static org .hibernate .reactive .util .impl .CompletionStages .failedFuture ;
4337import static org .hibernate .reactive .util .impl .CompletionStages .voidFuture ;
4438
4539public class DefaultReactiveLockEventListener extends DefaultLockEventListener implements LockEventListener , ReactiveLockEventListener {
@@ -53,15 +47,17 @@ public void onLock(LockEvent event) throws HibernateException {
5347
5448 @ Override
5549 public CompletionStage <Void > reactiveOnLock (LockEvent event ) throws HibernateException {
56- if ( event .getObject () == null ) {
50+ final Object instance = event .getObject ();
51+ if ( instance == null ) {
5752 throw new NullPointerException ( "attempted to lock null" );
5853 }
5954
60- if ( event .getLockMode () == LockMode .WRITE ) {
55+ final var lockMode = event .getLockMode ();
56+ if ( lockMode == LockMode .WRITE ) {
6157 throw LOG .invalidLockModeForLock ();
6258 }
6359
64- if ( event . getLockMode () == LockMode .UPGRADE_SKIPLOCKED ) {
60+ if ( lockMode == LockMode .UPGRADE_SKIPLOCKED ) {
6561 LOG .explicitSkipLockedLockCombo ();
6662 }
6763
@@ -80,54 +76,20 @@ public CompletionStage<Void> reactiveOnLock(LockEvent event) throws HibernateExc
8076 //TODO: if object was an uninitialized proxy, this is inefficient,
8177 // resulting in two SQL selects
8278
83- return ( (ReactiveQueryProducer ) source ).reactiveFetch ( event . getObject () , true )
79+ return ( (ReactiveQueryProducer ) source ).reactiveFetch ( instance , true )
8480 .thenCompose ( entity -> reactiveOnLock ( event , entity ) );
8581 }
8682
8783 private CompletionStage <Void > reactiveOnLock (LockEvent event , Object entity ) {
8884 final SessionImplementor source = event .getSession ();
8985 final PersistenceContext persistenceContext = source .getPersistenceContextInternal ();
9086 final EntityEntry entry = persistenceContext .getEntry ( entity );
91- return lockEntry ( event , entity , entry , source )
92- .thenCompose ( e -> upgradeLock ( entity , e , event .getLockOptions (), event .getSession () ) );
93- }
94-
95- private CompletionStage <EntityEntry > lockEntry (
96- LockEvent event ,
97- Object entity ,
98- EntityEntry entry ,
99- SessionImplementor source ) {
100- if ( entry == null ) {
101- final EntityPersister persister = source .getEntityPersister ( event .getEntityName (), entity );
102- final Object id = persister .getIdentifier ( entity , source );
103- return ForeignKeys
104- .isNotTransient ( event .getEntityName (), entity , Boolean .FALSE , source )
105- .thenCompose ( trans -> {
106- if ( !trans ) {
107- return failedFuture ( new TransientObjectException (
108- "Cannot lock unsaved transient instance of entity '" + persister .getEntityName () + "'"
109- ) );
110- }
111-
112- final EntityEntry e = reassociate ( event , entity , id , persister );
113- return cascadeOnLock ( event , persister , entity )
114- .thenApply ( v -> e );
115- }
116- );
87+ if ( entry == null && event .getObject () == entity ) {
88+ throw new DetachedObjectException ( "Given entity is not associated with the persistence context" );
11789 }
118- return completedFuture ( entry );
90+ return upgradeLock ( entity , entry , event . getLockOptions (), event . getSession () );
11991 }
12092
121- private CompletionStage <Void > cascadeOnLock (LockEvent event , EntityPersister persister , Object entity ) {
122- return Cascade .cascade (
123- CascadingActions .LOCK ,
124- CascadePoint .AFTER_LOCK ,
125- event .getSession (),
126- persister ,
127- entity ,
128- event .getLockOptions ()
129- );
130- }
13193
13294 /**
13395 * Performs a pessimistic lock upgrade on a given entity, if needed.
0 commit comments