hibernate/hibernate-orm · error · HibernateException

could not parse timestamp string %s

Error message

could not parse timestamp string %s

What it means

JdbcTimestampJavaType.fromString() parses timestamp literals with the strict pattern 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS' in UTC: a space separator and exactly nine fractional digits are required. Text in ISO form ('2024-01-01T10:00:00'), without nanoseconds, or with fewer/more fraction digits throws DateTimeParseException, wrapped as HibernateException("could not parse timestamp string ..."). Used when HQL timestamp literals are parsed and strings are converted to Timestamp.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JdbcTimestampJavaType.java:227

			default -> false;
		};
	}

	@Override
	public String toString(Timestamp value) {
		return LITERAL_FORMATTER.format( value.toInstant() );
	}

	@Override
	public Timestamp fromString(CharSequence string) {
		try {
			final var temporalAccessor = LITERAL_FORMATTER.parse( string );
			final var timestamp = new Timestamp( temporalAccessor.getLong( ChronoField.INSTANT_SECONDS ) * 1000L );
			timestamp.setNanos( temporalAccessor.get( ChronoField.NANO_OF_SECOND ) );
			return timestamp;
		}
		catch ( DateTimeParseException pe) {
			throw new HibernateException( "could not parse timestamp string " + string, pe );
		}
	}

	@Override
	public void appendEncodedString(SqlAppender sb, Timestamp value) {
		ENCODED_FORMATTER.formatTo( value.toInstant(), sb );
	}

	@Override
	public Timestamp fromEncodedString(CharSequence charSequence, int start, int end) {
		try {
			final var temporalAccessor = ENCODED_FORMATTER.parse( subSequence( charSequence, start, end ) );
			if ( temporalAccessor.isSupported( ChronoField.INSTANT_SECONDS ) ) {
				final var timestamp = new Timestamp( temporalAccessor.getLong( ChronoField.INSTANT_SECONDS ) * 1000L );
				timestamp.setNanos( temporalAccessor.get( ChronoField.NANO_OF_SECOND ) );
				return timestamp;
			}
			else {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use typed bind parameters (LocalDateTime, Instant or java.sql.Timestamp) instead of string literals - the recommended fix
  2. If a literal is required, format it as 'yyyy-MM-dd HH:mm:ss.fffffffff' with all nine fraction digits (e.g. '2024-01-01 10:00:00.000000000')
  3. Parse the incoming string yourself into a LocalDateTime/Instant and bind the object
  4. For string columns storing timestamps, add an AttributeConverter with the correct formatter

Example fix

// before
em.createQuery("select e from Log e where e.at = '2024-01-01T10:00:00'") // HibernateException

// after
query = em.createQuery("select e from Log e where e.at = :at", Log.class);
query.setParameter("at", LocalDateTime.parse("2024-01-01T10:00:00"));
Defensive patterns

Strategy: validation

Validate before calling

static final java.time.format.DateTimeFormatter HQL_TS =
    java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");

static boolean isParsableTimestampLiteral(CharSequence s) {
    try { HQL_TS.parse(s); return true; }
    catch (java.time.format.DateTimeParseException e) { return false; }
}

Type guard

static java.time.LocalDateTime tryParseHqlTimestamp(String s) {
    try { return java.time.LocalDateTime.parse(s.replace(' ', 'T')); }
    catch (Exception e) { return null; }
}

Try / catch

try { /* query with timestamp literal or fromString */ }
catch (HibernateException e) {
    if (e.getCause() instanceof DateTimeParseException)
        throw new IllegalArgumentException("Timestamp literal must be 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS'", e);
    throw e;
}

Prevention

When it happens

Trigger: HQL literal ... where e.at = '2024-01-01T10:00:00' or '2024-01-01 10:00:00' (missing .000000000); fromString on strings with 'T' separator; passing a String parameter where a Timestamp is expected by the query.

Common situations: Devs writing ISO-8601 literals in JPQL (natural habit, wrong format here); front-ends sending ISO strings that get spliced into queries; data feeds formatting timestamps with DateTimeFormatter.ISO_LOCAL_DATE_TIME.

Related errors


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