@@ -176,51 +176,65 @@ private void deleteDetachedEntity(
176176 }
177177
178178 final EntityKey key = source .generateEntityKey ( id , persister );
179- final Object version = persister .getVersion (entity );
179+ final Object version = persister .getVersion ( entity );
180180
181181// persistenceContext.checkUniqueness( key, entity );
182- flushAndEvictExistingEntity ( key , version , persister , source );
182+ if ( ! flushAndEvictExistingEntity ( key , version , persister , source ) ) {
183183
184- new OnUpdateVisitor ( source , id , entity ).process ( entity , persister );
184+ new OnUpdateVisitor ( source , id , entity ).process ( entity , persister );
185185
186- final PersistenceContext persistenceContext = source .getPersistenceContextInternal ();
187- final EntityEntry entityEntry = persistenceContext .addEntity (
188- entity ,
189- persister .isMutable () ? Status .MANAGED : Status .READ_ONLY ,
190- persister .getValues (entity ),
191- key ,
192- version ,
193- LockMode .NONE ,
194- true ,
195- persister ,
196- false
197- );
198- persister .afterReassociate (entity , source );
186+ final PersistenceContext persistenceContext = source .getPersistenceContextInternal ();
187+ final EntityEntry entityEntry = persistenceContext .addEntity (
188+ entity ,
189+ persister .isMutable () ? Status .MANAGED : Status .READ_ONLY ,
190+ persister .getValues (entity ),
191+ key ,
192+ version ,
193+ LockMode .NONE ,
194+ true ,
195+ persister ,
196+ false
197+ );
198+ persister .afterReassociate ( entity , source );
199199
200- delete ( event , transientEntities , source , entity , persister , id , version , entityEntry );
200+ delete ( event , transientEntities , source , entity , persister , id , version , entityEntry );
201+ }
201202 }
202203
203204 /**
204205 * Since Hibernate 7, if a detached instance is passed to remove(),
205206 * and if there is already an existing managed entity with the same
206207 * id, flush and evict it, after checking that the versions match.
208+ *
209+ * @return true if the managed entity was already deleted
207210 */
208- private static void flushAndEvictExistingEntity (
211+ private static boolean flushAndEvictExistingEntity (
209212 EntityKey key , Object version , EntityPersister persister , EventSource source ) {
210- final Object existingEntity = source .getPersistenceContextInternal ().getEntity ( key );
213+ final PersistenceContext persistenceContext = source .getPersistenceContextInternal ();
214+ final Object existingEntity = persistenceContext .getEntity ( key );
211215 if ( existingEntity != null ) {
212- LOG .flushAndEvictOnRemove ( key .getEntityName () );
213- source .flush ();
214- if ( !persister .isVersioned ()
215- || persister .getVersionType ()
216- .isEqual ( version , persister .getVersion ( existingEntity ) ) ) {
217- source .evict ( existingEntity );
216+ if ( persistenceContext .getEntry ( existingEntity ).getStatus ().isDeletedOrGone () ) {
217+ // already deleted, no work to do
218+ return true ;
218219 }
219220 else {
220- throw new StaleObjectStateException ( key .getEntityName (), key .getIdentifier (),
221- "Persistence context contains a more recent version of the given entity" );
221+ LOG .flushAndEvictOnRemove ( key .getEntityName () );
222+ source .flush ();
223+ if ( !persister .isVersioned ()
224+ || persister .getVersionType ()
225+ .isEqual ( version , persister .getVersion ( existingEntity ) ) ) {
226+ source .evict ( existingEntity );
227+ return false ;
228+ }
229+ else {
230+ throw new StaleObjectStateException ( key .getEntityName (), key .getIdentifier (),
231+ "Persistence context contains a more recent version of the given entity" );
232+ }
222233 }
223234 }
235+ else {
236+ return false ;
237+ }
224238 }
225239
226240 private void deletePersistentInstance (
0 commit comments