{"record":{"id":"f9c74e2a71dd781a","repo":"hibernate/hibernate-orm","slug":"no-add-foreign-key-syntax-supported-by-sqlitediale","errorCode":null,"errorMessage":"No add foreign key syntax supported by SQLiteDialect","messagePattern":"No add foreign key syntax supported by SQLiteDialect","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java","lineNumber":507,"sourceCode":"\n\t@Override\n\tpublic boolean qualifyIndexName() {\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getDropForeignKeyString() {\n\t\tthrow new UnsupportedOperationException( \"No drop foreign key syntax supported by SQLiteDialect\" );\n\t}\n\n\t@Override\n\tpublic String getAddForeignKeyConstraintString(\n\t\t\tString constraintName,\n\t\t\tString[] foreignKey,\n\t\t\tString referencedTable,\n\t\t\tString[] primaryKey,\n\t\t\tboolean referencesPrimaryKey) {\n\t\tthrow new UnsupportedOperationException( \"No add foreign key syntax supported by SQLiteDialect\" );\n\t}\n\n\t@Override\n\tpublic String getAddPrimaryKeyConstraintString(String constraintName) {\n\t\tthrow new UnsupportedOperationException( \"No add primary key syntax supported by SQLiteDialect\" );\n\t}\n\n\t@Override\n\tpublic boolean supportsCommentOn() {\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean supportsIfExistsBeforeTableName() {\n\t\treturn true;\n\t}\n\n\t@Override","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java#L489-L525","documentation":"getAddForeignKeyConstraintString(...) on SQLiteDialect unconditionally throws because SQLite cannot add a foreign key constraint with ALTER TABLE; FK constraints exist only as table constraints inside CREATE TABLE. Hibernate's schema migrator hits this method when, during hbm2ddl update, it wants to emit ALTER TABLE ADD CONSTRAINT for a new or changed association. The correct model on SQLite is to define the FK inline when the table is first created.","triggerScenarios":"Adding a new @ManyToOne/@OneToMany association to an entity while hibernate.hbm2ddl.auto=update runs against an existing SQLite table; SchemaExport update flows over changed mappings; generic DDL generators that emit add-constraint statements for every dialect.","commonSituations":"Iterating on an entity model with auto-DDL enabled in SQLite-based desktop/mobile/embedded apps; test suites that use SQLite in-memory with ddl-auto=update; porting a MySQL schema workflow to SQLite.","solutions":["Recreate the table with the FK inline in CREATE TABLE via a migration script (copy, drop, rename)","Keep associations in mappings so the FK is present from the initial CREATE TABLE and never needs an ALTER","Switch hibernate.hbm2ddl.auto to none (or validate) and manage DDL with Flyway/Liquibase","If generating DDL programmatically, skip ALTER-based constraint statements for SQLite"],"exampleFix":"// before - new association + auto-update => ALTER TABLE ADD CONSTRAINT (throws)\n// hibernate.hbm2ddl.auto = update\n\n// after - table created complete from day one\n// hibernate.hbm2ddl.auto = create (fresh DB) or none + migration:\n// CREATE TABLE orders (id integer primary key, customer_id integer REFERENCES customer(id));","handlingStrategy":"validation","validationCode":"static boolean supportsAlterConstraints(Dialect d) {\n    return d.hasAlterTable() && !(d instanceof SQLiteDialect);\n}\n\n// in DDL generation:\nif (supportsAlterConstraints(dialect)) {\n    ddl.add(dialect.getAddForeignKeyConstraintString(name, fk, table, pk, true));\n} else {\n    log.warn('dialect requires FKs inline in CREATE TABLE; emit a table rebuild migration');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat SQLite schema changes as table rebuilds, never ALTER statements","Validate mappings before enabling ddl-auto: every FK must exist at initial CREATE TABLE","Use Flyway/Liquibase for SQLite instead of hbm2ddl update"],"tags":["hibernate","sqlite","dialect","schema-migration","foreign-key","ddl","alter-table"],"backgroundTag":"schema-migration-unsupported-constraint","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}