@@ -176,51 +176,65 @@ private void deleteDetachedEntity(
176
176
}
177
177
178
178
final EntityKey key = source .generateEntityKey ( id , persister );
179
- final Object version = persister .getVersion (entity );
179
+ final Object version = persister .getVersion ( entity );
180
180
181
181
// persistenceContext.checkUniqueness( key, entity );
182
- flushAndEvictExistingEntity ( key , version , persister , source );
182
+ if ( ! flushAndEvictExistingEntity ( key , version , persister , source ) ) {
183
183
184
- new OnUpdateVisitor ( source , id , entity ).process ( entity , persister );
184
+ new OnUpdateVisitor ( source , id , entity ).process ( entity , persister );
185
185
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 );
199
199
200
- delete ( event , transientEntities , source , entity , persister , id , version , entityEntry );
200
+ delete ( event , transientEntities , source , entity , persister , id , version , entityEntry );
201
+ }
201
202
}
202
203
203
204
/**
204
205
* Since Hibernate 7, if a detached instance is passed to remove(),
205
206
* and if there is already an existing managed entity with the same
206
207
* id, flush and evict it, after checking that the versions match.
208
+ *
209
+ * @return true if the managed entity was already deleted
207
210
*/
208
- private static void flushAndEvictExistingEntity (
211
+ private static boolean flushAndEvictExistingEntity (
209
212
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 );
211
215
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 ;
218
219
}
219
220
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
+ }
222
233
}
223
234
}
235
+ else {
236
+ return false ;
237
+ }
224
238
}
225
239
226
240
private void deletePersistentInstance (
0 commit comments