{"record":{"id":"d01355b15e616653","repo":"hibernate/hibernate-orm","slug":"could-not-parse-date-string-s","errorCode":null,"errorMessage":"could not parse date string %s","messagePattern":"could not parse date string (.+?)","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JdbcDateJavaType.java","lineNumber":260,"sourceCode":"\tprivate static TemporalAccessor fromDate(java.util.Date value) {\n\t\treturn value instanceof java.sql.Date date\n\t\t\t\t? date.toLocalDate()\n\t\t\t\t: LocalDate.ofInstant( value.toInstant(), ZoneOffset.systemDefault() );\n\t}\n\n\t@Override\n\tpublic String toString(Date value) {\n\t\treturn LITERAL_FORMATTER.format( fromDate( value ) );\n\t}\n\n\t@Override\n\tpublic Date fromString(CharSequence string) {\n\t\ttry {\n\t\t\tfinal var temporalAccessor = LITERAL_FORMATTER.parse( string );\n\t\t\treturn java.sql.Date.valueOf( temporalAccessor.query( LocalDate::from ) );\n\t\t}\n\t\tcatch ( DateTimeParseException pe) {\n\t\t\tthrow new HibernateException( \"could not parse date string \" + string, pe );\n\t\t}\n\t}\n\n\t@Override\n\tpublic Date fromEncodedString(CharSequence charSequence, int start, int end) {\n\t\ttry {\n\t\t\tfinal var temporalAccessor = ENCODED_FORMATTER.parse( subSequence( charSequence, start, end ) );\n\t\t\treturn java.sql.Date.valueOf( temporalAccessor.query( LocalDate::from ) );\n\t\t}\n\t\tcatch ( DateTimeParseException pe) {\n\t\t\tthrow new HibernateException( \"could not parse time string \" + subSequence( charSequence, start, end ), pe );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void appendEncodedString(SqlAppender sb, Date value) {\n\t\tLITERAL_FORMATTER.formatTo( fromDate( value ), sb );\n\t}","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JdbcDateJavaType.java#L242-L278","documentation":"JdbcDateJavaType.fromString() parses date text using DateTimeFormatter.ISO_LOCAL_DATE, i.e. exactly yyyy-MM-dd. It is the path Hibernate uses to read HQL/JPQL date literals and to convert string data into java.sql.Date. If the text does not match ISO local date (regional format, time part, whitespace), the DateTimeParseException is rethrown as HibernateException(\"could not parse date string ...\").","triggerScenarios":"An HQL literal such as ... where e.d = '31/12/2024' or '2024.12.31' (only '2024-12-31' parses); calling JdbcDateJavaType.INSTANCE.fromString(...) or JavaType.fromString on a non-ISO string; a String-typed source (native query result, varchar column, XML mapping) coerced into a java.sql.Date attribute with non-ISO content, including empty strings and values with trailing spaces.","commonSituations":"Data imported from CSV/Excel with regional date formats; native SQL queries returning dates as formatted strings; reports or integrations that hand-formatted dates with SimpleDateFormat('dd/MM/yyyy') before binding; upgrades where hand-written literals no longer parse.","solutions":["Rewrite literals and stored text to ISO format yyyy-MM-dd before Hibernate sees them","In HQL, prefer bind parameters of type LocalDate or java.sql.Date over string literals","For a text column holding dates in a fixed non-ISO format, add a javax.persistence.AttributeConverter that parses with the matching DateTimeFormatter","Trim/clean the incoming strings; reject empty strings before they reach the parser"],"exampleFix":"// before\nem.createQuery(\"select e from Event e where e.day = '31/12/2024'\") // HibernateException\n\n// after\nem.createQuery(\"select e from Event e where e.day = '2024-12-31'\")\n// or: query.setParameter(\"day\", LocalDate.of(2024,12,31));","handlingStrategy":"validation","validationCode":"static boolean isIsoDate(CharSequence s) {\n    if (s == null) return false;\n    try { java.time.LocalDate.parse(s); return true; }\n    catch (java.time.format.DateTimeParseException e) { return false; }\n}\n\n// before binding/storing:\nif (!isIsoDate(text)) throw new IllegalArgumentException(\"Expected yyyy-MM-dd: \" + text);","typeGuard":"static java.time.LocalDate tryIsoDate(String s) {\n    try { return java.time.LocalDate.parse(s.trim()); } catch (Exception e) { return null; }\n}","tryCatchPattern":"try {\n    Date d = JdbcDateJavaType.INSTANCE.fromString(text);\n} catch (HibernateException e) {\n    if (e.getCause() instanceof DateTimeParseException pe)\n        throw new IllegalArgumentException(\"Bad date text: '\" + text + \"' (expected yyyy-MM-DD)\", e);\n    throw e;\n}","preventionTips":["Always bind typed LocalDate/java.sql.Date parameters instead of string literals","Normalize external date text to ISO with an explicit DateTimeFormatter at the boundary","Reject empty strings before they reach Hibernate parsing"],"tags":["hibernate","date-parsing","iso-local-date","hql-literal","datetimeformatter"],"backgroundTag":"datetime-string-parse-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}