{"record":{"id":"f202e74d4bc8a19d","repo":"spring-projects/spring-security","slug":"object-identity-objectidentity-already-exists","errorCode":null,"errorMessage":"Object identity '{objectIdentity}' already exists","messagePattern":"Object identity '(.+?)' already exists","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java","lineNumber":119,"sourceCode":"\n\tprivate String selectSidPrimaryKey = \"select id from acl_sid where principal=? and sid=?\";\n\n\tprivate String updateObjectIdentity = \"update acl_object_identity set \"\n\t\t\t+ \"parent_object = ?, owner_sid = ?, entries_inheriting = ?\" + \" where id = ?\";\n\n\tpublic JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {\n\t\tsuper(dataSource, lookupStrategy);\n\t\tAssert.notNull(aclCache, \"AclCache required\");\n\t\tthis.aclCache = aclCache;\n\t}\n\n\t@Override\n\tpublic MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException {\n\t\tAssert.notNull(objectIdentity, \"Object Identity required\");\n\n\t\t// Check this object identity hasn't already been persisted\n\t\tif (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {\n\t\t\tthrow new AlreadyExistsException(\"Object identity '\" + objectIdentity + \"' already exists\");\n\t\t}\n\n\t\t// Need to retrieve the current principal, in order to know who \"owns\" this ACL\n\t\t// (can be changed later on)\n\t\tAuthentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();\n\t\tAssert.isTrue(auth != null, \"Authentication required\");\n\t\tPrincipalSid sid = new PrincipalSid(auth);\n\n\t\t// Create the acl_object_identity row\n\t\tcreateObjectIdentity(objectIdentity, sid);\n\n\t\t// Retrieve the ACL via superclass (ensures cache registration, proper retrieval\n\t\t// etc)\n\t\tAcl acl = readAclById(objectIdentity);\n\t\tAssert.isInstanceOf(MutableAcl.class, acl, \"MutableAcl should be been returned\");\n\n\t\treturn (MutableAcl) acl;\n\t}","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java#L101-L137","documentation":"JdbcMutableAclService.createAcl first checks whether the given ObjectIdentity already has a row in acl_object_identity (via retrieveObjectIdentityPrimaryKey). If a primary key already exists, it throws AlreadyExistsException because ACLs are one-per-object-identity. This enforces the unique mapping between a domain object identity and its persisted ACL.","triggerScenarios":"Calling createAcl(objectIdentity) twice for the same ObjectIdentity, or calling createAcl for an object whose ACL row already exists because a previous transaction/request (or another node) created it.","commonSituations":"Retry logic or event listeners that run createAcl on every entity save without an existence check; concurrent requests creating the ACL for the same new entity; redeploying an initialization job that seeds ACLs; hot-reload/restart re-running bootstrap data setup.","solutions":["Check existence before creating: only call createAcl when retrieveObjectIdentityPrimaryKey (or readAclById) indicates no ACL exists.","Catch org.springframework.security.acls.model.AlreadyExistsException and treat the existing ACL as the outcome.","Guard concurrent creation with a transaction/unique constraint and retry the read after AlreadyExistsException.","Make bootstrap/seed code idempotent (create-or-get pattern)."],"exampleFix":"// before\nMutableAcl acl = mutableAclService.createAcl(oid);\n// after\nMutableAcl acl;\ntry {\n    acl = mutableAclService.createAcl(oid);\n} catch (AlreadyExistsException ex) {\n    acl = (MutableAcl) aclService.readAclById(oid);\n}","handlingStrategy":"try-catch","validationCode":"if (mutableAclService.retrieveObjectIdentityPrimaryKey(oid) != null) {\n    // already exists — skip creation\n}","typeGuard":"null","tryCatchPattern":"try {\n    acl = mutableAclService.createAcl(oid);\n} catch (AlreadyExistsException e) {\n    acl = (MutableAcl) aclService.readAclById(oid);\n}","preventionTips":["Use a create-or-get helper for ACL provisioning","Make seed/bootstrap scripts idempotent","Serialize ACL creation for the same oid across concurrent requests"],"tags":["spring-security","acl","duplicate","database"],"backgroundTag":"file-already-exists","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}