hibernate/hibernate-orm · error · SchemaExtractionException

More than one table found in namespace (%s, %s) : %s

Error message

More than one table found in namespace (%s, %s) : %s

What it means

While extracting table metadata (schema validate/update/migration, reverse engineering), Hibernate walks the JDBC resultset looking for the requested table inside the namespace. More than one row resolving to the same requested Identifier means two physically distinct objects match — typically differing only in quoting or case — so extraction aborts with SchemaExtractionException rather than silently choosing one.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/AbstractInformationExtractorImpl.java:805

	}

	private TableInformation extractTableInformation(
			Identifier catalog,
			Identifier schema,
			Identifier tableName,
			ResultSet resultSet)
					throws SQLException {

		boolean found = false;
		TableInformation tableInformation = null;
		while ( resultSet.next() ) {
			final Identifier identifier =
					toIdentifier( resultSet.getString( getResultSetTableNameLabel() ),
							tableName.isQuoted() );
			if ( tableName.equals( identifier ) ) {
				if ( found ) {
					CORE_LOGGER.multipleTablesFound( tableName.render() );
					throw new SchemaExtractionException(
							String.format(
									Locale.ENGLISH,
									"More than one table found in namespace (%s, %s) : %s",
									catalog == null ? "" : catalog.render(),
									schema == null ? "" : schema.render(),
									tableName.render()
							)
					);
				}
				else {
					found = true;
					tableInformation = extractTableInformation( resultSet );
					addColumns( tableInformation );
				}
			}
		}
		if ( !found ) {
			CORE_LOGGER.tableNotFound( tableName.render() );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Make the mapping's identifiers match the physical objects exactly: adjust @Table/@Column names, quoting, or the physical naming strategy.
  2. Scope the extraction: set hibernate.default_catalog / hibernate.default_schema (or the connection's current schema) so only the intended namespace is searched.
  3. Rename or drop the accidental duplicate table when it is not intentional.

Example fix

// before
@Entity
@Table(name = "user") // collides with USER in the same schema
public class User { ... }

// after
@Entity
@Table(name = "app_user")
public class User { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

try (ResultSet rs = connection.getMetaData().getTables(catalog, schema, "%", new String[]{"TABLE"})) {
    Map<String, Integer> seen = new HashMap<>();
    while (rs.next()) {
        String key = (rs.getString(2) + "." + rs.getString(3)).toLowerCase(Locale.ROOT);
        seen.merge(key, 1, Integer::sum);
    }
    // any key with count > 1 after case-folding => collision risk before hbm2ddl runs
}

Try / catch

try {
    schemaValidator.validate(metadata, databaseModel);
} catch (SchemaExtractionException e) {
    // e.getMessage() names the namespace and colliding table — fix quoting/naming, then re-run
    throw e;
}

Prevention

When it happens

Trigger: Running hbm2ddl validate/update or hibernate-tools against a schema containing case/quoting-colliding tables (e.g. USER and "User") while the mapping asks for the unquoted name; drivers that match identifiers case-insensitively return multiple matches for the equality check.

Common situations: PostgreSQL/Oracle/H2 schemas with mixed-case legacy names; mappings that quote identifiers (backticks or global quoting) while the physical objects are unquoted, or vice versa; same table name in several catalogs when the catalog scope is unset.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/c68548d145a62b0e. Report an issue: GitHub.