hibernate/hibernate-orm · error · SchemaManagementException
SQL strings added more than once for:
Error message
SQL strings added more than once for:
What it means
The drop path applies the same one-SQL-per-exportable invariant as creation: while building DROP statements SchemaDropperImpl records each Exportable's export identifier, and a second occurrence of the same identifier throws this SchemaManagementException. The object named in the message is registered twice in the Metadata being dropped, so the mapping is ambiguous, not the database.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java:488
&& schemaFilter.includeTable( table )
&& inclusionFilter.matches( table ) ) {
for ( var foreignKey : table.getForeignKeyCollection() ) {
applySqlStrings(
dialect.getForeignKeyExporter().getSqlDropStrings( foreignKey, metadata, context ),
formatter,
options,
targets
);
}
}
}
}
}
private static void checkExportIdentifier(Exportable exportable, Set<String> exportIdentifiers) {
final String exportIdentifier = exportable.getExportIdentifier();
if ( exportIdentifiers.contains( exportIdentifier ) ) {
throw new SchemaManagementException( "SQL strings added more than once for: " + exportIdentifier );
}
exportIdentifiers.add( exportIdentifier );
}
@Override
public DelayedDropAction buildDelayedAction(
Metadata metadata,
ExecutionOptions options,
ContributableMatcher inclusionFilter,
SourceDescriptor sourceDescriptor) {
final var target = new JournalingGenerationTarget();
final var dialect = tool.getServiceRegistry().requireService( JdbcEnvironment.class ).getDialect();
doDrop( metadata, options, inclusionFilter, dialect, sourceDescriptor, target );
return new DelayedDropActionImpl( target.commands, tool.getCustomDatabaseGenerationTarget() );
}
/**
* For testsView on GitHub (pinned to fad1729dce)
Solutions
- Grep mappings for the identifier in the message and de-duplicate the registration so the object is mapped once.
- If the overlap is intentional (e.g., view and table sharing a name), rename one object so the export identifiers differ.
- Check MetadataSources construction for addResource/addAnnotatedClass calls that resolve to the same mapping, and persistence.xml mapping-file entries for duplicates.
Example fix
// before
MetadataSources sources = new MetadataSources(registry)
.addAnnotatedClass(Order.class)
.addResource("/mappings/Order.hbm.xml"); // same class mapped twice
// after
MetadataSources sources = new MetadataSources(registry)
.addAnnotatedClass(Order.class); Defensive patterns
Strategy: validation
Validate before calling
// before dropping, assert each mapped table name is registered exactly once
Set<String> names = new HashSet<>();
metadata.collectTableMappings(s -> names.add(s) == false, ...); // pseudo: collect export identifiers
if (names.size() != expectedUniqueCount) { /* refuse to drop, report duplicates */ } Try / catch
try {
schemaManagementTool.getSchemaDropper(settings).doDrop(metadata, false, source, options, targetDescriptor);
} catch (SchemaManagementException e) {
if (e.getMessage() != null && e.getMessage().startsWith("SQL strings added more than once for:")) {
String exportable = e.getMessage().substring(e.getMessage().lastIndexOf(' ') + 1);
// de-duplicate the mapping for `exportable` before re-running the drop
} else { throw e; }
} Prevention
- Run a create-export (STDOUT) against new mappings in CI — it catches duplicates before drop/create-drop ever runs.
- Keep mapping registration centralized; avoid merging MetadataSources from overlapping modules.
- Audit auxiliary database objects when both XML and annotations are in play.
When it happens
Trigger: Running drop, drop-and-create, or drop-only schema management (SchemaExport.drop, hbm2ddl drop/create-drop teardown) over Metadata that maps the same table/sequence/UDT/auxiliary object twice. Same root causes as the create-side guard: duplicate entity table names, doubly-registered mapping classes, or duplicated auxiliary database objects.
Common situations: Test profiles using drop-and-create that hit a refactoring artifact (two entities on one table); the same hbm.xml resource included via two classpath entries; @AuxiliaryDatabaseObject present in both an annotated class and an XML mapping; multi-module projects merging overlapping MetadataSources.
Related errors
- SQL strings added more than once for:
- SQL strings added more than once for:
- unknown type: {sqlTypeCode}
- Error creating SQL 'create' commands for table '
- No drop schema syntax supported by " + getClass().getName()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/ece11cdd56d4aeee.
Report an issue: GitHub.