1414import org .hibernate .cache .spi .entry .CacheEntry ;
1515import org .hibernate .engine .spi .EntityEntry ;
1616import org .hibernate .engine .spi .EntityKey ;
17+ import org .hibernate .engine .spi .PersistenceContext ;
1718import org .hibernate .engine .spi .SessionFactoryImplementor ;
1819import org .hibernate .engine .spi .SharedSessionContractImplementor ;
1920import org .hibernate .event .spi .EventSource ;
2021import org .hibernate .persister .entity .EntityPersister ;
2122import org .hibernate .reactive .persister .entity .impl .ReactiveEntityPersister ;
23+ import org .hibernate .stat .internal .StatsHelper ;
24+ import org .hibernate .stat .spi .StatisticsImplementor ;
2225
2326import static org .hibernate .reactive .util .impl .CompletionStages .voidFuture ;
2427
@@ -50,74 +53,76 @@ public void execute() throws HibernateException {
5053
5154 @ Override
5255 public CompletionStage <Void > reactiveExecute () throws HibernateException {
56+ final CompletionStage <Void > stage = reactiveNullifyTransientReferencesIfNotAlready ();
57+
58+ final EntityPersister persister = getPersister ();
59+ final SharedSessionContractImplementor session = getSession ();
60+ final Object instance = getInstance ();
61+ final Object id = getId ();
62+
63+ // FIXME: It needs to become async
64+ final boolean veto = preInsert ();
65+
66+ // Don't need to lock the cache here, since if someone
67+ // else inserted the same pk first, the insert would fail
68+ if ( !veto ) {
69+ final ReactiveEntityPersister reactivePersister = (ReactiveEntityPersister ) persister ;
70+ final PersistenceContext persistenceContext = session .getPersistenceContextInternal ();
71+ return stage
72+ .thenCompose ( v -> reactivePersister .insertReactive ( id , getState (), instance , session ) )
73+ .thenApply ( res -> {
74+ final EntityEntry entry = persistenceContext .getEntry ( instance );
75+ if ( entry == null ) {
76+ throw new AssertionFailure ( "possible non-threadsafe access to session" );
77+ }
78+ entry .postInsert ( getState () );
79+ return entry ;
80+ } )
81+ .thenCompose ( entry -> processInsertGeneratedProperties ( reactivePersister , session , instance , id , entry ) )
82+ .thenAccept ( vv -> {
83+ persistenceContext .registerInsertedKey ( persister , getId () );
84+ addCollectionsByKeyToPersistenceContext ( persistenceContext , getState () );
85+ putCacheIfNecessary ();
86+ handleNaturalIdPostSaveNotifications ( id );
87+ postInsert ();
88+
89+ final StatisticsImplementor statistics = session .getFactory ().getStatistics ();
90+ if ( statistics .isStatisticsEnabled () && !veto ) {
91+ statistics .insertEntity ( getPersister ().getEntityName () );
92+ }
93+
94+ markExecuted ();
95+ } );
96+ }
97+ else {
98+ putCacheIfNecessary ();
99+ handleNaturalIdPostSaveNotifications ( id );
100+ postInsert ();
101+ markExecuted ();
102+ return stage ;
103+ }
104+ }
53105
54- return reactiveNullifyTransientReferencesIfNotAlready ().thenCompose ( v -> {
55-
56- EntityPersister persister = getPersister ();
57- final SharedSessionContractImplementor session = getSession ();
58- final Object instance = getInstance ();
59- final Object id = getId ();
60-
61- // FIXME: It needs to become async
62- final boolean veto = preInsert ();
63-
64- // Don't need to lock the cache here, since if someone
65- // else inserted the same pk first, the insert would fail
66- CompletionStage <Void > insertStage ;
67- if ( !veto ) {
68- ReactiveEntityPersister reactivePersister = (ReactiveEntityPersister ) persister ;
69- insertStage = reactivePersister .insertReactive ( id , getState (), instance , session )
70- .thenApply ( res -> {
71- EntityEntry entry = session .getPersistenceContext ().getEntry ( instance );
72- if ( entry == null ) {
73- throw new AssertionFailure ( "possible non-threadsafe access to session" );
74- }
75- entry .postInsert ( getState () );
76- return entry ;
77- } )
78- .thenCompose ( entry -> processInsertGeneratedProperties ( reactivePersister , session , instance , id , entry )
79- .thenAccept ( vv -> session .getPersistenceContext ().registerInsertedKey ( persister , getId () ) ) );
80- }
81- else {
82- insertStage = voidFuture ();
106+ //TODO: copy/paste from superclass (make it protected)
107+ private void putCacheIfNecessary () {
108+ final EntityPersister persister = getPersister ();
109+ final SharedSessionContractImplementor session = getSession ();
110+ if ( isCachePutEnabled ( persister , session ) ) {
111+ final SessionFactoryImplementor factory = session .getFactory ();
112+ final CacheEntry ce = persister .buildCacheEntry ( getInstance (), getState (), getVersion (), session );
113+ setCacheEntry ( persister .getCacheEntryStructure ().structure ( ce ) );
114+ final EntityDataAccess cache = persister .getCacheAccessStrategy ();
115+ final Object ck = cache .generateCacheKey ( getId (), persister , factory , session .getTenantIdentifier () );
116+ final boolean put = cacheInsert ( persister , ck );
117+
118+ final StatisticsImplementor statistics = factory .getStatistics ();
119+ if ( put && statistics .isStatisticsEnabled () ) {
120+ statistics .entityCachePut (
121+ StatsHelper .INSTANCE .getRootEntityRole ( persister ),
122+ cache .getRegion ().getName ()
123+ );
83124 }
84-
85- return insertStage .thenApply ( res -> {
86- final SessionFactoryImplementor factory = session .getFactory ();
87-
88- if ( isCachePutEnabled ( persister , session ) ) {
89- final CacheEntry ce = persister .buildCacheEntry (
90- instance ,
91- getState (),
92- getVersion (),
93- session
94- );
95- setCacheEntry ( persister .getCacheEntryStructure ().structure ( ce ) );
96- final EntityDataAccess cache = persister .getCacheAccessStrategy ();
97- final Object ck = cache .generateCacheKey ( id , persister , factory , session .getTenantIdentifier () );
98-
99- final boolean put = cacheInsert ( persister , ck );
100-
101- if ( put && factory .getStatistics ().isStatisticsEnabled () ) {
102- factory .getStatistics ().entityCachePut (
103- persister .getNavigableRole (),
104- persister .getCacheAccessStrategy ().getRegion ().getName ()
105- );
106- }
107- }
108-
109- handleNaturalIdPostSaveNotifications ( id );
110-
111- postInsert ();
112-
113- if ( factory .getStatistics ().isStatisticsEnabled () && !veto ) {
114- factory .getStatistics ().insertEntity ( getEntityName () );
115- }
116-
117- markExecuted ();
118- return null ;
119- } );
120- } );
125+ }
121126 }
122127
123128 private CompletionStage <Void > processInsertGeneratedProperties (
@@ -135,7 +140,9 @@ private CompletionStage<Void> processInsertGeneratedProperties(
135140 .thenAccept ( v -> entry .postUpdate ( instance , getState (), getVersion () ) );
136141
137142 }
138- return voidFuture ();
143+ else {
144+ return voidFuture ();
145+ }
139146 }
140147
141148 @ Override
0 commit comments