Fix ON_CONFLICT_NOTHING cascade causing FK violation (#3712)#3818
Merged
Conversation
When inserting a bean with InsertOptions.ON_CONFLICT_NOTHING that has cascade children (OneToMany / exported OneToOne), a unique constraint conflict caused the parent insert to be silently skipped (0 rows), but Ebean still cascaded and attempted to insert the children — resulting in a FK violation. Changes • BeanDescriptor.hasCascadeChildren() — returns true when the bean has save-cascade children (OneToMany or exported OneToOne) that hold a FK back to this bean. • PersistRequestBean.setInsertOptions() — when ON_CONFLICT_NOTHING is used and the bean has cascade children, sets skipBatchForTopLevel = true so the parent INSERT executes immediately (non-batched). This ensures the row count is known before any cascade runs. Beans without cascade children are unaffected and continue to batch normally. • PersistRequestBean.checkRowCount() — when the parent INSERT returns 0 rows under ON_CONFLICT_NOTHING, sets insertConflictSkipped = true and returns early, leaving the bean unmarked as loaded/persisted. • DmlHandler.checkRowCount() — skips postExecute() when the insert was conflict-skipped. • DefaultPersister.insert() — guards saveAssocMany() with !request.isInsertConflictSkipped(), preventing cascade saves when the parent was not actually inserted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When inserting a bean with InsertOptions.ON_CONFLICT_NOTHING that has cascade children (OneToMany / exported OneToOne), a unique constraint conflict caused the parent insert to be silently skipped (0 rows), but Ebean still cascaded and attempted to insert the children — resulting in a FK violation.
Changes
• BeanDescriptor.hasCascadeChildren() — returns true when the bean has save-cascade children (OneToMany or exported OneToOne) that hold a FK back to this bean. • PersistRequestBean.setInsertOptions() — when ON_CONFLICT_NOTHING is used and the bean has cascade children, sets skipBatchForTopLevel = true so the parent INSERT executes immediately (non-batched). This ensures the row count is known before any cascade runs. Beans without cascade children are unaffected and continue to batch normally. • PersistRequestBean.checkRowCount() — when the parent INSERT returns 0 rows under ON_CONFLICT_NOTHING, sets insertConflictSkipped = true and returns early, leaving the bean unmarked as loaded/persisted. • DmlHandler.checkRowCount() — skips postExecute() when the insert was conflict-skipped. • DefaultPersister.insert() — guards saveAssocMany() with !request.isInsertConflictSkipped(), preventing cascade saves when the parent was not actually inserted.