hibernate/hibernate-orm · error · IllegalQueryOperationException

Insert conflict 'do update' clause with constraint name is n

Error message

Insert conflict 'do update' clause with constraint name is not supported

What it means

SybaseASESqlAstTranslator.visitConflictClause rejects HQL INSERT ... ON CONFLICT statements whose conflict target is a named constraint: when the ConflictClause is a DO UPDATE clause and getConstraintName() != null, it throws IllegalQueryOperationException, because the ASE upsert rendering cannot resolve conflicts through a constraint name (no 'ON CONFLICT ON CONSTRAINT' equivalent in ASE SQL).

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java:122

	}

	@Override
	protected void renderFromClauseAfterUpdateSet(UpdateStatement statement) {
		if ( statement.getFromClause().getRoots().isEmpty() ) {
			appendSql( " from " );
			renderDmlTargetTableExpression( statement.getTargetTable() );
			renderTableReferenceIdentificationVariable( statement.getTargetTable() );
		}
		else {
			visitFromClause( statement.getFromClause() );
		}
	}

	@Override
	protected void visitConflictClause(ConflictClause conflictClause) {
		if ( conflictClause != null ) {
			if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) {
				throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" );
			}
		}
	}

	// Sybase ASE does not allow CASE expressions where all result arms contain plain parameters.
	// At least one result arm must provide some type context for inference,
	// so we cast the first result arm if we encounter this condition

	@Override
	protected void visitAnsiCaseSearchedExpression(
			CaseSearchedExpression caseSearchedExpression,
			Consumer<Expression> resultRenderer) {
		if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( caseSearchedExpression ) ) {
			final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
			final Expression firstResult = whenFragments.get( 0 ).getResult();
			super.visitAnsiCaseSearchedExpression(
					caseSearchedExpression,
					e -> {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use the column-based form 'on conflict (col1, col2) do update set ...'
  2. Verify the column list covers exactly the columns of the intended unique constraint
  3. Use a native ASE statement (MERGE where supported, or IF EXISTS ... UPDATE ELSE INSERT) for dialect-specific upserts
  4. Branch on dialect at runtime so PostgreSQL keeps the constraint-name form and ASE gets the column form

Example fix

// before
"insert into Price p (p.sku,p.value) values (:s,:v) on conflict on constraint uk_price_sku do update set p.value = excluded.value"

// after
"insert into Price p (p.sku,p.value) values (:s,:v) on conflict (sku) do update set p.value = excluded.value"
Defensive patterns

Strategy: validation

Validate before calling

static boolean supportsConstraintNameConflictTarget(Dialect dialect) {
    return dialect instanceof PostgreSQLDialect; // Sybase ASE translator rejects it
}

if (!supportsConstraintNameConflictTarget(dialect)) {
    hql = hql.replace("on conflict on constraint " + constraintName,
                     "on conflict (" + constraintColumns + ")");
}

Try / catch

try {
    em.createQuery(hql).executeUpdate();
} catch (IllegalQueryOperationException e) {
    if (e.getMessage().contains("constraint name is not supported")) {
        em.createQuery(toColumnTargetHql(hql)).executeUpdate();
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Executing HQL 'insert into T (...) values/select ... on conflict on constraint <name> do update set ...' (or SQM conflictOnConstraint("<name>")) while the factory uses SybaseASEDialect. The exception is thrown during query translation (createQuery/executeUpdate), before any DB call.

Common situations: Running PostgreSQL-derived upsert HQL against an ASE database; shared cross-dialect test suites; legacy Sybase deployments receiving code written for PostgreSQL dialect.

Related errors


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