{"record":{"id":"792593503cd79412","repo":"hibernate/hibernate-orm","slug":"no-drop-foreign-key-syntax-supported-by-sqlitedial","errorCode":null,"errorMessage":"No drop foreign key syntax supported by SQLiteDialect","messagePattern":"No drop 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":497,"sourceCode":"\t@Override\n\tpublic boolean hasAlterTable() {\n\t\t// As specified in NHibernate dialect\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean dropConstraints() {\n\t\treturn false;\n\t}\n\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","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java#L479-L515","documentation":"getDropForeignKeyString() on SQLiteDialect unconditionally throws because SQLite has no ALTER TABLE ... DROP FOREIGN KEY syntax: foreign keys can only be declared inline in CREATE TABLE. Hibernate's schema migrator reaches this method when it must drop an FK constraint during hbm2ddl update/drop processing. The dialect also reports dropConstraints() == false, so well-behaved tooling should skip the call entirely; hitting it usually means automatic schema management is being forced onto SQLite.","triggerScenarios":"Running SchemaUpdate or SchemaExport drop (hibernate.hbm2ddl.auto=update/create-drop) over mappings whose FK constraints change or must be dropped; custom DDL utilities that ask every dialect for drop-foreign-key SQL.","commonSituations":"Entity model changed (removed or renamed @ManyToOne) while auto-DDL runs against a SQLite file or in-memory test database; a shared schema-management utility treats all dialects alike; migrating an app from MySQL to SQLite without changing DDL strategy.","solutions":["Manage the SQLite schema with versioned migrations (Flyway/Liquibase) and set hibernate.hbm2ddl.auto=none","To change FKs, recreate the table using SQLite's documented ALTER recipe: create new table with correct CREATE TABLE, copy data, drop old, rename","Declare FKs inline via @ManyToOne/@JoinColumn so they are correct at initial table creation and never need an ALTER","In custom tooling, check dialect.dropConstraints() before requesting drop-FK SQL"],"exampleFix":"// before - auto schema management on SQLite tries DROP FOREIGN KEY\n// hibernate.hbm2ddl.auto = update\n\n// after - explicit migration only\n// hibernate.hbm2ddl.auto = none\n// V2__recreate_order.sql:\n// CREATE TABLE order_new (... REFERENCES customer(id));\n// INSERT INTO order_new SELECT * FROM order;\n// DROP TABLE order;\n// ALTER TABLE order_new RENAME TO order;","handlingStrategy":"validation","validationCode":"Dialect dialect = sessionFactory.getJdbcServices().getDialect();\nif (dialect.dropConstraints()) {\n    ddl.add(dialect.getDropForeignKeyString());\n}\n// SQLite reports dropConstraints() == false: skip drop-FK DDL instead of throwing","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never run hbm2ddl auto-update against SQLite for constraint changes; ship recreate-table migrations","Gate every constraint-DDL generator on dialect.dropConstraints() and hasAlterTable()","Keep FK declarations inline in CREATE TABLE from the start"],"tags":["hibernate","sqlite","dialect","schema-migration","foreign-key","ddl"],"backgroundTag":"schema-migration-unsupported-constraint","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}