spring-projects/spring-security · error · AlreadyExistsException

Object identity '{objectIdentity}' already exists

Error message

Object identity '{objectIdentity}' already exists

What it means

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.

Source

Thrown at acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java:119

	private String selectSidPrimaryKey = "select id from acl_sid where principal=? and sid=?";

	private String updateObjectIdentity = "update acl_object_identity set "
			+ "parent_object = ?, owner_sid = ?, entries_inheriting = ?" + " where id = ?";

	public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {
		super(dataSource, lookupStrategy);
		Assert.notNull(aclCache, "AclCache required");
		this.aclCache = aclCache;
	}

	@Override
	public MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException {
		Assert.notNull(objectIdentity, "Object Identity required");

		// Check this object identity hasn't already been persisted
		if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {
			throw new AlreadyExistsException("Object identity '" + objectIdentity + "' already exists");
		}

		// Need to retrieve the current principal, in order to know who "owns" this ACL
		// (can be changed later on)
		Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
		Assert.isTrue(auth != null, "Authentication required");
		PrincipalSid sid = new PrincipalSid(auth);

		// Create the acl_object_identity row
		createObjectIdentity(objectIdentity, sid);

		// Retrieve the ACL via superclass (ensures cache registration, proper retrieval
		// etc)
		Acl acl = readAclById(objectIdentity);
		Assert.isInstanceOf(MutableAcl.class, acl, "MutableAcl should be been returned");

		return (MutableAcl) acl;
	}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Check existence before creating: only call createAcl when retrieveObjectIdentityPrimaryKey (or readAclById) indicates no ACL exists.
  2. Catch org.springframework.security.acls.model.AlreadyExistsException and treat the existing ACL as the outcome.
  3. Guard concurrent creation with a transaction/unique constraint and retry the read after AlreadyExistsException.
  4. Make bootstrap/seed code idempotent (create-or-get pattern).

Example fix

// before
MutableAcl acl = mutableAclService.createAcl(oid);
// after
MutableAcl acl;
try {
    acl = mutableAclService.createAcl(oid);
} catch (AlreadyExistsException ex) {
    acl = (MutableAcl) aclService.readAclById(oid);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (mutableAclService.retrieveObjectIdentityPrimaryKey(oid) != null) {
    // already exists — skip creation
}

Type guard

null

Try / catch

try {
    acl = mutableAclService.createAcl(oid);
} catch (AlreadyExistsException e) {
    acl = (MutableAcl) aclService.readAclById(oid);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/f202e74d4bc8a19d. Report an issue: GitHub.