hibernate/hibernate-orm · error · MappingException

The INSERT statement for table [%s] contains no column, and

Error message

The INSERT statement for table [%s] contains no column, and this is not supported by [%s]

What it means

While rendering an INSERT statement, Hibernate found zero columns to include — every mapped column of the table is generated, virtual, or insertable=false. If the dialect does not support no-column inserts (supportsNoColumnsInsert() == false, e.g. Oracle), it cannot produce valid SQL and throws MappingException naming the table and the dialect.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/Insert.java:136

		this.tableName = tableName;
		return this;
	}

	public String toStatementString() {
		final StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 );

		if ( comment != null ) {
			buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " );
		}

		buf.append( "insert into " ).append( tableName );

		if ( columns.isEmpty() ) {
			if ( dialect.supportsNoColumnsInsert() ) {
				buf.append( ' ' ).append( dialect.getNoColumnsInsertString() );
			}
			else {
				throw new MappingException(
						String.format(
								"The INSERT statement for table [%s] contains no column, and this is not supported by [%s]",
								tableName,
								dialect
						)
				);
			}
		}
		else {
			buf.append( " (" );
			renderInsertionSpec( buf );
			buf.append( ") values (" );
			renderRowValues( buf );
			buf.append( ')' );
		}
		return buf.toString();
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the entity at least one insertable column the application can write
  2. Check dialect capability up front: dialect.supportsNoColumnsInsert() — if false, such mappings cannot be inserted via Hibernate
  3. For trigger/default-populated tables with no writable columns, use a native SQL insert or a @SQLInsert override
  4. Revisit insertable=false / @Generated usage — you may have accidentally excluded every column

Example fix

// before
@Entity
@Table(name = "audit_log")
public class AuditLog {
    @Id @GeneratedValue Long id;              // generated
    @Column(insertable = false) String user;  // DB default -> zero insertable columns on Oracle
}

// after
@Entity
@Table(name = "audit_log")
public class AuditLog {
    @Id @GeneratedValue Long id;
    String user; // let Hibernate insert it (or use a native insert)
Defensive patterns

Strategy: validation

Validate before calling

// startup audit: mappings with zero insertable columns need dialect support
Dialect dialect = sessionFactory.getJdbcServices().getDialect();
if (!dialect.supportsNoColumnsInsert()) {
    for (EntityBinding b : metadata.getEntityBindings()) {
        if (b.getInsertableColumnCount() == 0) {
            LOG.error("table {} has no insertable columns; dialect {} cannot insert it",
                      b.getTableName(), dialect);
        }
    }
}

Prevention

When it happens

Trigger: An entity whose columns are all database-generated (defaults, triggers, identity) being persisted on a dialect without 'insert into t default values' support; mappings where every column has insertable=false; insert-only generated properties with no regular columns left.

Common situations: Audit/log tables populated entirely by triggers; tables where the app supplies no columns; switching an application from SQL Server/H2 (supports DEFAULT VALUES) to Oracle; overuse of insertable=false in composite mappings.

Related errors


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