{"record":{"id":"d2e3cf670ec32201","repo":"hibernate/hibernate-orm","slug":"illegal-state-writer-null-not-prepared","errorCode":null,"errorMessage":"Illegal state : writer null - not prepared","messagePattern":"Illegal state : writer null - not prepared","errorType":"exception","errorClass":"SchemaManagementException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ScriptTargetOutputToFile.java","lineNumber":59,"sourceCode":"\t\tthis.append = append;\n\t}\n\n\t/**\n\t * Constructs a ScriptTargetOutputToFile instance,\n\t * the bytes will be written to the end of the file rather than the beginning\n\t *\n\t * @param file The file to read from\n\t * @param charsetName The charset name\n\t *\n\t */\n\tpublic ScriptTargetOutputToFile(File file, String charsetName ) {\n\t\tthis(file, charsetName, true);\n\t}\n\n\t@Override\n\tprotected Writer writer() {\n\t\tif ( writer == null ) {\n\t\t\tthrow new SchemaManagementException( \"Illegal state : writer null - not prepared\" );\n\t\t}\n\t\treturn writer;\n\t}\n\n\t@Override\n\tpublic void prepare() {\n\t\tsuper.prepare();\n\t\tthis.writer = toFileWriter( this.file, this.charsetName, append );\n\t}\n\n\t@Override\n\tpublic void release() {\n\t\tif ( writer != null ) {\n\t\t\ttry {\n\t\t\t\twriter.close();\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new SchemaManagementException( \"Unable to close file writer : \" + e );","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ScriptTargetOutputToFile.java#L41-L77","documentation":"ScriptTargetOutputToFile creates its FileWriter lazily in prepare() and nulls it in release(); writer() throws this SchemaManagementException when a write is attempted while the writer is null — i.e. before prepare() or after release(). It is a lifecycle-contract violation inside the script-target plumbing; stock hbm2ddl calls prepare/write/release in order, so users normally hit it only through custom schema tooling.","triggerScenarios":"Calling write() on a ScriptTargetOutputToFile without calling prepare() first; reusing the same target for a second export after release() has run (release() sets writer=null); custom SchemaManagementTool/GenerationTarget code orchestrating the target lifecycle out of order.","commonSituations":"Custom integrations that build their own GenerationTargets; interrupted schema generation where release() already executed and a later phase tries to write again; copies of Hibernate examples that skip prepare().","solutions":["Call prepare() before any write and release() exactly once at the end — mirror SchemaExport's ordering.","Never reuse a ScriptTargetOutputToFile after release(); construct a fresh instance for each export run.","If this surfaces during plain hbm2ddl with no custom code, upgrade hibernate-core — lifecycle sequencing bugs were fixed in patches."],"exampleFix":"// before: writing before/outside the lifecycle\nScriptTargetOutput out = new ScriptTargetOutputToFile( file, null );\nout.write( \"create table ...\" ); // IllegalStateException-style failure\n\n// after: explicit lifecycle\nout.prepare();\nout.write( \"create table ...\" );\nout.release();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    target.prepare();\n    target.write( ddl );\n}\nfinally {\n    target.release(); // release() must run even if write fails, so state is clean for a fresh instance\n}","preventionTips":["Treat ScriptTargetOutput as single-use: one prepare/write/release cycle per export run.","Never call write() before prepare() returns; assert the lifecycle in custom integrations.","Create a fresh ScriptTargetOutputToFile for retries instead of reusing the released instance."],"tags":["hibernate","schema-management","lifecycle","script-target"],"backgroundTag":"resource-not-initialized","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}