{"record":{"id":"742b55164ba7c1d4","repo":"hibernate/hibernate-orm","slug":"cannot-delete-instance-of-entity-persister-gete","errorCode":null,"errorMessage":"Cannot delete instance of entity '${persister.getEntityName()}' because it has a null identifier","messagePattern":"Cannot delete instance of entity '(.+?)' because it has a null identifier","errorType":"exception","errorClass":"TransientObjectException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/event/internal/DefaultDeleteEventListener.java","lineNumber":169,"sourceCode":"\t\t\tdeleteTransientEntity( source, entity, persister, transientEntities );\n\t\t}\n\t\telse {\n\t\t\tdeleteDetachedEntity( event, transientEntities, entity, persister, source );\n\t\t}\n\t}\n\n\tprivate void deleteDetachedEntity(\n\t\t\t@Nonnull DeleteEvent event,\n\t\t\t@Nonnull DeleteContext transientEntities,\n\t\t\t@Nonnull Object entity,\n\t\t\t@Nonnull EntityPersister persister,\n\t\t\t@Nonnull EventSource source) {\n\t\tif ( source.getFactory().getSessionFactoryOptions().isJpaBootstrap() ) {\n\t\t\tthrow new DetachedObjectException( \"Given entity is not associated with the persistence context\" );\n\t\t}\n\t\tfinal Object id = persister.getIdentifier( entity, source );\n\t\tif ( id == null ) {\n\t\t\tthrow new TransientObjectException( \"Cannot delete instance of entity '\"\n\t\t\t\t\t+ persister.getEntityName() + \"' because it has a null identifier\" );\n\t\t}\n\n\t\tfinal var key = source.generateEntityKey( id, persister);\n\t\tfinal Object version = persister.getVersion( entity );\n\n//\t\tpersistenceContext.checkUniqueness( key, entity );\n\t\tif ( !flushAndEvictExistingEntity( key, version, persister, source ) ) {\n\n\t\t\tnew OnUpdateVisitor( source, id, entity ).process( entity, persister );\n\n\t\t\tfinal var entityEntry =\n\t\t\t\t\tsource.getPersistenceContextInternal()\n\t\t\t\t\t\t\t.addEntity(\n\t\t\t\t\t\t\t\t\tentity,\n\t\t\t\t\t\t\t\t\tpersister.isMutable() ? Status.MANAGED : Status.READ_ONLY,\n\t\t\t\t\t\t\t\t\tpersister.getValues( entity ),\n\t\t\t\t\t\t\t\t\tkey,","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultDeleteEventListener.java#L151-L187","documentation":"On the native-bootstrap delete path for detached entities, deleteDetachedEntity() reads the identifier and finds null — the object is transient, not detached, so there is nothing to delete by. Hibernate throws TransientObjectException('Cannot delete instance of entity ... because it has a null identifier').","triggerScenarios":"session.remove/delete(new Customer()) on an object that was never saved; entity whose id getter returns null because the mapping reads the wrong field or the id was reset; deleting an object whose identifier was never populated by the assembler.","commonSituations":"Delete handlers receiving empty request payloads that map to fresh instances; id field nulled during DTO copying; entities with application-assigned ids that were never set before delete.","solutions":["Null-check the identifier before calling delete/remove","If the id is absent, treat it as a no-op or a validation error rather than calling Hibernate","Delete by id with a JPQL mutation query when you only have the key","Fix the id mapping/getter if the row exists in the database but the entity reads null"],"exampleFix":"// before\nsession.remove(customer); // customer.id == null -> TransientObjectException\n\n// after\nif (customer.getId() != null) {\n    session.remove(customer);\n}\n// or delete by id\nsession.createMutationQuery(\"delete from Customer c where c.id = :id\")\n       .setParameter(\"id\", id)\n       .executeUpdate();","handlingStrategy":"validation","validationCode":"if (customer.getId() == null) {\n    throw new IllegalArgumentException(\"cannot delete a transient \" + Customer.class.getSimpleName());\n}\nsession.remove(customer);","typeGuard":"static boolean isDeletable(Customer c) {\n    return c != null && c.getId() != null;\n}","tryCatchPattern":null,"preventionTips":["Null-check the identifier before every delete call","Delete by id via JPQL when only the key is known","Validate request payloads before mapping them onto entities for deletion","Watch for DTO mappers that drop the id field"],"tags":["delete","transient-object","identifier-generation","session"],"backgroundTag":"delete-transient-entity","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}