hibernate/hibernate-orm · error · IllegalStateException

Duplicate column: {}

Error message

Duplicate column: {}

What it means

SqmJsonTableFunction tracks every column name in a set; column(), nested(), and ordinalityColumn() definitions funnel through addColumn(), which throws IllegalStateException('Duplicate column: name') when the name was already registered. Column names in the COLUMNS clause must be unique because they become tuple component names and SQL column aliases.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmJsonTableFunction.java:293

	public <X> JpaJsonValueNode<X> valueColumn(String columnName, JpaCastTarget<X> type) {
		return columns.valueColumn( columnName, type );
	}

	@Override
	public JpaJsonTableColumnsNode nested(String jsonPath) {
		return columns.nested( jsonPath );
	}

	@Override
	public JpaJsonTableFunction ordinalityColumn(String columnName) {
		columns.ordinalityColumn( columnName );
		return this;
	}

	private void addColumn(String columnName) {
		checkTypeResolved();
		if ( !columnNames.add( columnName ) ) {
			throw new IllegalStateException( "Duplicate column: " + columnName );
		}
	}

	private void checkTypeResolved() {
		if ( isTypeResolved() ) {
			throw new IllegalStateException(
					"Type for json_table function is already resolved. Mutation is not allowed anymore" );
		}
	}

	@Override
	public boolean equals(@Nullable Object object) {
		return object instanceof SqmJsonTableFunction<?> that
			&& super.equals( object )
			&& columns.equals( that.columns )
			&& Objects.equals( passingExpressions, that.passingExpressions )
			&& errorBehavior == that.errorBehavior;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. De-duplicate the column list by name before building the function.
  2. Rename one of the colliding columns - the SQL output name is independent of the JSON path, so alias it (e.g. id vs. id_ord).
  3. When generating names dynamically, uniquify them (append an index) before calling column()/ordinalityColumn().

Example fix

// before
t.ordinalityColumn( "id" );  // a path column "id" was already added -> Duplicate column: id

// after
t.ordinalityColumn( "id_ord" );
Defensive patterns

Strategy: validation

Validate before calling

Set<String> usedColumnNames = new HashSet<>();

void addJsonTableColumn(String name, Runnable definer) {
    if ( !usedColumnNames.add( name ) ) {
        throw new IllegalArgumentException( "json_table column already defined: " + name );
    }
    definer.run();
}

Prevention

When it happens

Trigger: Defining the same column name twice on a json_table criteria node: a path column named "id" plus ordinalityColumn("id"), two path columns sharing one name, or nested columns whose chosen names collide with top-level ones.

Common situations: Loop-generated column lists containing duplicates; merging column definitions from several config sources; renames that accidentally produce a collision; names derived from JSON keys that repeat at different levels.

Related errors


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