elunez/eladmin · warning · EntityExistException
${className} with ${column.columnName} {} existed
Error message
${className} with ${column.columnName} {} existed What it means
Not a runtime throw but a FreeMarker template line in the code generator (ServiceImpl.ftl): for every column flagged UNIQUE in the inspected table, the generated service's create() calls `repository.findBy<Column>(...) != null` and throws EntityExistException("${className} with ${column.columnName} {} existed", value). At generation time the placeholders ${className}/${column.columnName} are filled; at runtime of the GENERATED code this fires when inserting a row whose unique column value already exists.
Source
Thrown at eladmin-generator/src/main/resources/template/admin/ServiceImpl.ftl:103
ValidationUtil.isNull(${changeClassName}.get${pkCapitalColName}(),"${className}","${pkChangeColName}",${pkChangeColName});
return ${changeClassName}Mapper.toDto(${changeClassName});
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(${className} resources) {
<#if !auto && pkColumnType = 'Long'>
Snowflake snowflake = IdUtil.createSnowflake(1, 1);
resources.set${pkCapitalColName}(snowflake.nextId());
</#if>
<#if !auto && pkColumnType = 'String'>
resources.set${pkCapitalColName}(IdUtil.simpleUUID());
</#if>
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
if(${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()) != null){
throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
}
</#if>
</#list>
</#if>
${changeClassName}Repository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(${className} resources) {
${className} ${changeClassName} = ${changeClassName}Repository.findById(resources.get${pkCapitalColName}()).orElseGet(${className}::new);
ValidationUtil.isNull( ${changeClassName}.get${pkCapitalColName}(),"${className}","id",resources.get${pkCapitalColName}());
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
<#if column_index = 1>
${className} ${changeClassName}1 = null;
</#if>View on GitHub (pinned to 55fbf70595)
Solutions
- Submit a value not yet present for the unique column (check via the generated list/query endpoint first).
- If duplicates keep occurring from double clicks, debounce/disable the submit button until the response.
- For concurrent creates, rely on/also handle the DB unique constraint (catch DataIntegrityViolationException) since the findBy-then-save check is not atomic.
- Adjust the .ftl template to generate an upsert or a friendlier message if you control the generator templates.
- Regenerate the module after changing the table's unique keys so the guards match reality.
Example fix
// before (generated code pattern)
if(userRepository.findByUsername(resources.getUsername()) != null){
throw new EntityExistException(User.class, "username", resources.getUsername());
}
userRepository.save(resources);
// after: also handle the race via the DB constraint
try {
userRepository.save(resources);
} catch (DataIntegrityViolationException e) {
throw new EntityExistException(User.class, "username", resources.getUsername());
} Defensive patterns
Strategy: validation
Validate before calling
// pre-check uniqueness through the generated query API
boolean taken = client.getByUsername(dto.getUsername()) != null;
if (taken) { toast('用户名已存在'); return; } Try / catch
try { create(dto); } catch (EntityExistException e) { // e.getMessage() contains "with username ... existed": show duplicate-field error on that input } catch (DataIntegrityViolationException e) { // race lost to the DB constraint: same user-facing message } Prevention
- Disable submit buttons during in-flight creates to stop double submits.
- Remember the findBy check is not atomic — unique DB constraints remain the real guarantee.
- Regenerate modules after altering unique keys so guards match the schema.
When it happens
Trigger: Generating a module from a table with one or more UNIQUE-key columns, then calling the generated POST create endpoint with a value for that column that is already stored — e.g. creating a user with an existing username, a dict with an existing name.
Common situations: Duplicate submissions in the generated admin UI; import scripts colliding with existing rows; race conditions where two concurrent creates pass the findBy check and the DB unique constraint then throws a DataIntegrityViolationException instead; tables whose unique index is composite (this template only guards single-column UNI).
Related errors
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/445e9c367f3b9fc7.
Report an issue: GitHub.