{"record":{"id":"7fbf7000de6f5744","repo":"hibernate/hibernate-orm","slug":"cannot-parse-given-string-into-array-of-strings-f-7fbf70","errorCode":null,"errorMessage":"Cannot parse given string into array of strings. First and last character must be { and }","messagePattern":"Cannot parse given string into array of strings\\. First and last character must be (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java","lineNumber":287,"sourceCode":"\t\t\t}\n\t\t\tstring.append( '\"' );\n\t\t\tglue = \",\";\n\t\t}\n\t\tstring.append( '}' );\n\t\treturn string.toString();\n\t}\n\n\t@Override\n\tpublic C fromString(CharSequence charSequence) {\n\t\tif ( charSequence == null ) {\n\t\t\treturn null;\n\t\t}\n\t\tjava.util.ArrayList<String> list = new java.util.ArrayList<>();\n\t\tStringBuilder sb = null;\n\t\tchar lastChar = charSequence.charAt( charSequence.length() - 1 );\n\t\tchar firstChar = charSequence.charAt( 0 );\n\t\tif ( firstChar != '{' || lastChar != '}' ) {\n\t\t\tthrow new IllegalArgumentException( \"Cannot parse given string into array of strings. First and last character must be { and }\" );\n\t\t}\n\t\tint len = charSequence.length();\n\t\tboolean inquote = false;\n\t\tfor ( int i = 1; i < len; i ++ ) {\n\t\t\tchar c = charSequence.charAt( i );\n\t\t\tif ( c == '\"' ) {\n\t\t\t\tif (inquote) {\n\t\t\t\t\tlist.add( sb.toString() );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsb = new StringBuilder();\n\t\t\t\t}\n\t\t\t\tinquote = !inquote;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if ( !inquote ) {\n\t\t\t\tif ( Character.isWhitespace( c ) ) {\n\t\t\t\t\tcontinue;","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java#L269-L305","documentation":"The basic-collection JavaType also parses array literals back into a Collection<String>. fromString() first verifies the literal is brace-delimited: first char '{', last char '}', mirroring the exact format its own toString() emits. Any other shape (plain CSV, JSON array, null-adjacent strings) is rejected with this IllegalArgumentException before any element is parsed.","triggerScenarios":"Restoring a string-materialized basic collection from 'a,b,c'; a native query or ETL job writing comma-joined text into an array-typed column; passing a hand-built string to the descriptor directly; cache or replication layers that reformat the literal.","commonSituations":"Array-typed collections stored on varchar columns; data migrations that stripped braces; dialects without native arrays where the literal round-trips as text but producers do not add braces.","solutions":["Round-trip values exactly as toString() produces them: {\"a\",\"b\"} with braces around the whole literal (and each element quoted)","Bind the collection object itself and let Hibernate format the literal — never hand-build it","If the column genuinely holds plain CSV, map it as String with an AttributeConverter that splits into the collection instead of an array/basic-collection type"],"exampleFix":"// before\nString csv = \"red,green\";\nList<String> colors = (List<String>) basicCollectionJavaType.fromString(csv); // throws\n\n// after\nString literal = \"{\\\"red\\\",\\\"green\\\"}\";\nList<String> colors = (List<String>) basicCollectionJavaType.fromString(literal);","handlingStrategy":"validation","validationCode":"static boolean looksLikeArrayLiteral(CharSequence s) {\n    return s == null || (s.length() >= 2 && s.charAt(0) == '{' && s.charAt(s.length() - 1) == '}');\n}\n\nif (!looksLikeArrayLiteral(raw)) {\n    raw = '{' + raw + '}'; // or reject: only apply when you know the producer's format\n}","typeGuard":null,"tryCatchPattern":"try {\n    Collection<String> c = basicCollectionJavaType.fromString(raw);\n} catch (IllegalArgumentException e) {\n    // producer used plain CSV — fall back to a manual split\n    List<String> c = raw.isEmpty() ? List.of() : List.of(raw.split(\",\"));\n}","preventionTips":["Treat array columns as opaque — write collection objects, never hand-built strings","Keep a write+read round-trip test for every array-mapped attribute","Do not run string functions (replace, trim, join) over array literals in SQL"],"tags":["hibernate","orm","array","collection","parsing"],"backgroundTag":"array-string-parse-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}