diff --git a/app/model/entity/ExerciseFileLink.php b/app/model/entity/ExerciseFileLink.php index 5646ca8a2..2319c3367 100644 --- a/app/model/entity/ExerciseFileLink.php +++ b/app/model/entity/ExerciseFileLink.php @@ -13,8 +13,11 @@ * I.e., when Assignment is created from Exercise, the links are copied (immediately) as well. * The link of an exercise may be updated, but the link of an assignment is immutable. * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"key", "exercise_id"}), - * @ORM\UniqueConstraint(columns={"key", "assignment_id"})}) + * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"key", "exercise_id"})}) + * + * Note: technically, there should be also unique constraint on (key, assignment_id); however, it causes more problems + * than it solves. During sync operation, the assignment-related links are cleared and re-filled. Since the Doctrine + * performs inserts before deletes, and we do not want to flush in the middle, it causes unique constraint violation. */ class ExerciseFileLink implements JsonSerializable { diff --git a/migrations/Version20251214183529.php b/migrations/Version20251214183529.php new file mode 100644 index 000000000..9b6a7c129 --- /dev/null +++ b/migrations/Version20251214183529.php @@ -0,0 +1,31 @@ +addSql('DROP INDEX UNIQ_1187F7758A90ABA9D19302F8 ON exercise_file_link'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE UNIQUE INDEX UNIQ_1187F7758A90ABA9D19302F8 ON exercise_file_link (`key`, assignment_id)'); + } +}