hibernate/hibernate-orm · error · IllegalArgumentException
Inconsistent types for cycle mark values: [{}, {}]
Error message
Inconsistent types for cycle mark values: [{}, {}] What it means
cycle(...) wraps cycleValue and noCycleValue in SqmLiteral expressions and compares getNodeType() of the two literals; if the types differ (for example a String mark vs an Integer mark, or boolean vs int) it throws IllegalArgumentException listing both types. The two cycle mark values must map to the same node type so the rendered SQL has consistent column types.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/cte/SqmCteStatement.java:317
String cyclePathAttributeName,
X cycleValue,
X noCycleValue,
List<JpaCteCriteriaAttribute> cycleAttributes) {
if ( cycleMarkAttributeName == null || cycleAttributes == null || cycleAttributes.isEmpty() ) {
this.cycleMarkAttributeName = null;
this.cyclePathAttributeName = null;
this.cycleValue = null;
this.noCycleValue = null;
this.cycleAttributes = Collections.emptyList();
}
else {
if ( cycleValue == null || noCycleValue == null ) {
throw new IllegalArgumentException( "Null is an illegal value for cycle mark values!" );
}
final SqmExpression<X> cycleValueLiteral = nodeBuilder().literal( cycleValue );
final SqmExpression<X> noCycleValueLiteral = nodeBuilder().literal( noCycleValue );
if ( cycleValueLiteral.getNodeType() != noCycleValueLiteral.getNodeType() ) {
throw new IllegalArgumentException( "Inconsistent types for cycle mark values: [" + cycleValueLiteral.getNodeType() + ", " + noCycleValueLiteral.getNodeType() + "]" );
}
final List<SqmCteTableColumn> attributes = new ArrayList<>( cycleAttributes.size() );
for ( JpaCteCriteriaAttribute cycleAttribute : cycleAttributes ) {
if ( !cteTable.getAttributes().contains( cycleAttribute ) ) {
throw new IllegalArgumentException(
"Illegal cycle attribute '" +
( cycleAttribute == null ? "null" : cycleAttribute.getName() ) +
"' passed, which is not part of the JpaCteCriteria!"
);
}
attributes.add( (SqmCteTableColumn) cycleAttribute );
}
this.cycleMarkAttributeName = cycleMarkAttributeName;
this.cyclePathAttributeName = cyclePathAttributeName;
this.cycleValue = (SqmLiteral<Object>) cycleValueLiteral;
this.noCycleValue = (SqmLiteral<Object>) noCycleValueLiteral;
this.cycleAttributes = attributes;
}View on GitHub (pinned to fad1729dce)
Solutions
- Use a matching pair of the same type: true/false, 1/0 or "Y"/"N".
- Type the helper method as <X> and take both values as X so the compiler enforces identical types.
Example fix
// before cte.cycle( "isCycle", "path", true, 1, columns ); // boolean vs int // after cte.cycle( "isCycle", "path", true, false, columns );
Defensive patterns
Strategy: validation
Validate before calling
static <X> void assertSameType(X cycleValue, X noCycleValue) {
if ( !cycleValue.getClass().equals( noCycleValue.getClass() ) ) {
throw new IllegalArgumentException( "Cycle mark values must share one type" );
}
}
// then: cte.cycle( "m", "p", v1, v2, cols ); Prevention
- Always pass a literal pair of one type: true/false, 1/0 or "Y"/"N".
- Type helper methods as <X> cycle(String, String, X, X, List<...>) so both values share the compile-time type.
- Remember the comparison happens on the SQM literal node type after literal() conversion.
When it happens
Trigger: cte.cycle("isCycle", "path", true, 1, columns), or ("isCycle", "path", "T", 0, columns): any pair where the values have different runtime types producing different literal node types.
Common situations: Loosely-typed helper code where the two values come from different sources (config vs constant); changing one literal ('Y' vs 1) during refactoring; boxed types that differ between the two parameters.
Related errors
- Null is an illegal value for cycle mark values!
- Illegal cycle attribute '{}' passed, which is not part of th
- Illegal empty CTE name
- Illegal CTE name [%s]. Names must start with an alphabetic c
- Illegal search order attribute '{}' passed, which is not par
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a62e8f08205d3e68.
Report an issue: GitHub.