core icon indicating copy to clipboard operation
core copied to clipboard

Unique constraint violation on put

Open KDederichs opened this issue 2 years ago • 0 comments

API Platform version(s) affected: 3.1.8

Description
When you try to update an API Resource that contains a doctrine collection of Entities that are not an API Resource and define a Unique Index, the update will fail since it will try to recreate the collection entities.

How to reproduce
Have like this entities:

#[Entity]
#[ApiResource]
class Foo {
 // ...
     #[OneToMany(mappedBy: 'foo', targetEntity: Bar::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
    #[Valid]
    private Collection $bars;

     public function getBars(): Collection
    {
        return $this->bars;
    }

    public function setBars(Collection $bars): Foo
    {
        $this->bars = $bars;
        return $this;
    }


    public function addBar(Bar $bar): Foo
    {
        if (!$this->bars->contains($bar)) {
            $bar->foo($this);
            $this->bars->add($bar);
        }

        return $this;
    }

    public function removeBar(Bar $bar): Foo
    {
        if ($this->bars->contains($bar)) {
            $this->bars->removeElement($bar);
        }

        return $this;
    }
}

and

#[Entity]
#[UniqueConstraint(fields: ['foo', 'barType'])]
#[UniqueEntity(fields: ['foo', 'barType'])]
class Bar {
    #[ManyToOne(targetEntity: BarType::class)]
    #[JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private BarType $barType;
    #[ManyToOne(targetEntity: Foo::class, inversedBy: 'bars')]
    #[JoinColumn(nullable: false, onDelete: 'CASCADE')]
    #[Ignore]
    private Foo $foo;
    private string $barVal;

//...
}

and

#[Entity]
#[ApiResource]
#[Get]
#[GetCollection]
class BarType {
//...
}

If you then try to make a PUT request with a payload that already contains a Bar

{
 "@id": "/api/foos/1"
 "@type": "Foo"
"id": 1,
 "bars": [
  {
    "barType": "/api/bar_types/1"
   "barVal": "Test"
  }
 ]
}

element it will always result in a constraint violation since it'll try to re-create the Bar

Possible Solution
Optimally Api Platform would not need to recreate the non Api Resource entities, that would fix it.

KDederichs avatar Sep 25 '23 12:09 KDederichs