hibernate/hibernate-orm · error · IllegalArgumentException

Illegal precision: " + resolvedPrecision

Error message

Illegal precision: " + resolvedPrecision

What it means

ClockHelper.forPrecision picks the java.time.Clock used by @CurrentTimestamp-style generators for a fractional-second precision; after clamping with Math.min(resolvedPrecision, maxPrecision) the value must be 0-9. A negative resolved precision — an explicitly negative mapping precision, or a dialect getDefaultTimestampPrecision() below zero when precision is unset — falls through to default and throws IllegalArgumentException('Illegal precision: n').

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClockHelper.java:70

	}

	public static Clock forPrecision(int resolvedPrecision, int maxPrecision) {
		return forPrecision( null, resolvedPrecision, maxPrecision );
	}

	public static Clock forPrecision(@Nullable Clock baseClock, int resolvedPrecision, int maxPrecision) {
		return switch ( Math.min( resolvedPrecision, maxPrecision ) ) {
			case 0 -> baseClock == null ? TICK_0 : Clock.tick( baseClock, Duration.ofNanos( 1000000000L ) );
			case 1 -> baseClock == null ? TICK_1 : Clock.tick( baseClock, Duration.ofNanos( 100000000L ) );
			case 2 -> baseClock == null ? TICK_2 : Clock.tick( baseClock, Duration.ofNanos( 10000000L ) );
			case 3 -> baseClock == null ? TICK_3 : Clock.tick( baseClock, Duration.ofNanos( 1000000L ) );
			case 4 -> baseClock == null ? TICK_4 : Clock.tick( baseClock, Duration.ofNanos( 100000L ) );
			case 5 -> baseClock == null ? TICK_5 : Clock.tick( baseClock, Duration.ofNanos( 10000L ) );
			case 6 -> baseClock == null ? TICK_6 : Clock.tick( baseClock, Duration.ofNanos( 1000L ) );
			case 7 -> baseClock == null ? TICK_7 : Clock.tick( baseClock, Duration.ofNanos( 100L ) );
			case 8 -> baseClock == null ? TICK_8 : Clock.tick( baseClock, Duration.ofNanos( 10L ) );
			case 9 -> baseClock == null ? TICK_9 : baseClock;
			default -> throw new IllegalArgumentException( "Illegal precision: " + resolvedPrecision );
		};
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Set an explicit precision between 0 and 9 on the @CurrentTimestamp/@CreationTimestamp mapping.
  2. Upgrade to a built-in dialect whose getDefaultTimestampPrecision() is valid (0-9).
  3. For a custom dialect, implement getDefaultTimestampPrecision() to return a value in 0-9.

Example fix

// before
@CurrentTimestamp(source = VM, precision = -1) // or dialect default of -1
private Instant updated; // ClockHelper.forPrecision -> IllegalArgumentException

// after
@CurrentTimestamp(source = VM, precision = 6)
private Instant updated;
Defensive patterns

Strategy: validation

Validate before calling

static boolean isLegalPrecision(int p, int max) {
    return p >= 0 && Math.min(p, max) <= 9;
}
// assert before boot: if (configuredPrecision != null && !isLegalPrecision(configuredPrecision, 9)) fail fast with config error

Prevention

When it happens

Trigger: Setting @CurrentTimestamp(precision = -1) or any negative precision; leaving precision null on a dialect (often a custom/older one) whose default timestamp precision returns a negative sentinel like -1.

Common situations: Custom or community dialects reporting -1 for 'unknown' default precision; copy-pasting -1 'unknown' constants from SqlTypes into precision; Hibernate upgrades changing how precision is resolved for a database.

Related errors


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