{"record":{"id":"28cb8f070122219a","repo":"hibernate/hibernate-orm","slug":"duplicate-row-was-found-and-s-was-specified","errorCode":null,"errorMessage":"Duplicate row was found and `%s` was specified","messagePattern":"Duplicate row was found and `(.+?)` was specified","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/results/spi/ListResultsConsumer.java","lineNumber":262,"sourceCode":"\t\t\tRowReader<R> rowReader,\n\t\t\tResults<R> results) {\n\t\tint readRows = 0;\n\t\twhile ( rowProcessingState.next() ) {\n\t\t\tresults.add( rowReader.readRow( rowProcessingState ) );\n\t\t\trowProcessingState.finishRowProcessing( true );\n\t\t\treadRows++;\n\t\t}\n\t\treturn readRows;\n\t}\n\n\tprivate static <R> int readUniqueAssert(\n\t\t\tRowProcessingStateStandardImpl rowProcessingState,\n\t\t\tRowReader<R> rowReader,\n\t\t\tResults<R> results) {\n\t\tint readRows = 0;\n\t\twhile ( rowProcessingState.next() ) {\n\t\t\tif ( !results.addUnique( rowReader.readRow( rowProcessingState ) ) ) {\n\t\t\t\tthrow new HibernateException(\n\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\t\"Duplicate row was found and `%s` was specified\",\n\t\t\t\t\t\t\t\tUniqueSemantic.ASSERT\n\t\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t\trowProcessingState.finishRowProcessing( true );\n\t\t\treadRows++;\n\t\t}\n\t\treturn readRows;\n\t}\n\n\tprivate static <R> int readUnique(\n\t\t\tRowProcessingStateStandardImpl rowProcessingState,\n\t\t\tRowReader<R> rowReader,\n\t\t\tResults<R> results) {\n\t\tint readRows = 0;","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/spi/ListResultsConsumer.java#L244-L280","documentation":"Thrown by ListResultsConsumer.readUniqueAssert when a query runs under UniqueSemantic.ASSERT: every row read must be distinct, and results.addUnique detected a row equal (per the result JavaType) to one already collected. ASSERT is applied primarily by the internal by-id load plan (SingleIdLoadPlan uses ASSERT when a single result is expected), i.e. `EntityManager.find`/`session.find`, and only when the row reader has no collection initializers. Genuine duplicates for a primary-key load mean the mapping does not guarantee one row per id.","triggerScenarios":"`em.find(Employee.class, id)` where the entity is mapped to a database view containing the id twice; JOINED inheritance with the same id present in two subclass tables; a custom `@Loader`/`@SQLSelect` returning the same id more than once; broken data where a 'unique' key used for loading is not actually unique.","commonSituations":"Read-only reporting entities mapped onto views without a unique key; denormalized tables feeding entity mappings; data corruption or manual inserts breaking subclass-table uniqueness; custom loader SQL with an accidental cross join duplicating rows.","solutions":["Fix the underlying data or mapping so at most one row exists per primary key (dedupe the view/table, add the missing unique constraint)","For JOINED inheritance, delete the duplicate id rows from the extra subclass table(s) so each id lives in exactly one subclass","Fix custom `@Loader`/`@SQLSelect` SQL to return a unique row (add the right predicate or `distinct` on the id)","As a stopgap, load via a query with `UniqueSemantic`-tolerant semantics (e.g. a plain JPQL `where e.id = :id`) instead of `find()` to observe the duplicates, then fix the data"],"exampleFix":"// before: entity mapped to a view with duplicate ids -> em.find throws\nEmployee e = em.find(Employee.class, id);\n// after: dedupe the view (SQL) so each id appears once, keep em.find\ncreate view employee_v as select distinct on (id) * from employee_raw;","handlingStrategy":"validation","validationCode":"// Prove the load key is unique before relying on em.find (e.g. for view-backed entities)\nLong cnt = em.createQuery(\"select count(*) from EmployeeViewBacked e where e.businessKey = :k\", Long.class)\n             .setParameter(\"k\", key).getSingleResult();\nif (cnt != 1) throw new IllegalStateException(\"Load key not unique: \" + key + \" (\" + cnt + \" rows)\");","typeGuard":null,"tryCatchPattern":"catch (org.hibernate.HibernateException e) { if (e.getMessage() != null && e.getMessage().contains(\"Duplicate row was found\")) { /* data issue: dedupe, fix view/inheritance/custom loader */ } throw e; }","preventionTips":["Back by-id loads with a real primary key or unique constraint (views need a unique key too)","For JOINED inheritance, keep each id in exactly one subclass table - enforce and monitor this","Test custom @Loader/@SQLSelect SQL returns exactly one row for one id","Add a data-quality check for duplicate ids on view/denormalized tables in CI or ops dashboards"],"tags":["entity-loading","duplicate-rows","primary-key","joined-inheritance","find-by-id","unique-semantic"],"backgroundTag":"duplicate-rows-query-result","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}