0
Symfony : 4.4
API PLATFORM : 2.5 

I have to entities : Client & Location : a client have many locations, a location is related to one client

Client Entity:

    /**
 * @ORM\Entity(repositoryClass="App\Repository\ClientRepository")
 *
 *
 * @ApiResource(
 *     normalizationContext={"clients:get"},
 *     collectionOperations={
 *          "get"={
 *              "normalization_context": { "groups" = {"clients:get"} },
 *          },
 *          "post"={
 *               "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')",
 *               "normalization_context": { "groups" = {"client:get"} },
 *               "denormalization_context": { "groups" = {"client:create"} },
 *               "method"="POST",
 *               "controller"=ClientCreate::class
 *          }
 *     },
 *     itemOperations={
 *          "get"={
 *              "normalization_context": { "groups" = {"clients:get"} },
 *           },
 *          "put"={
 *               "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')",
 *               "normalization_context": { "groups" = {"client:get"} },
 *               "denormalization_context": { "groups" = {"client:put"} },
 *          },
 *     }
 * )
 *
 */
class Client implements UserInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     *
     * @Groups({"clients:get"})
     *
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Location", mappedBy="client", cascade={"persist", "remove"}), orphanRemoval=true)
     *
     *@Groups({"client:create","client:get","client:put"})
     *
     * @ApiSubresource()
     *
     */
    private $locations;

Location Entity:

/**
 * @ORM\Entity(repositoryClass="App\Repository\LocationRepository")
 *
 * @ApiResource()
 *
 */
class Location
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     *
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     *
     * @Groups({"client:create","client:get","client:put"})
     *
     */
    private $address;

//... others attributes

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @Groups({"client:create","client:get","client:put"})
     *
     */
    private $locationName;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Client", inversedBy="locations", fetch="EXTRA_LAZY")
     * @ORM\JoinColumn(nullable=false)
     */
    private $client;

I'm trying to make the relation Client-Location behaves like when I create a client => locations are created => that's works OK for me with this code. and also I want when I put a client, its old locations are removed, and It creates a new locations that are attached to this client but I got error in put.

Action PUT /api/clients/58 Body:

{
    "locations": [
        {
            "address": "dfsdfaaaaaaaa",
            "locationName": "sdfsdf"
        }
    ]
}

RESPONSE:

{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "An exception occurred while executing 'UPDATE location SET client_id = ? WHERE id = ?' with params [null, 24]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'client_id' cannot be null",
"trace": [
    {
        "namespace": "",
        "short_class": "",
        "class": "",
        "type": "",
        "function": "",
        "file": "/home/karimengineer/Desktop/SystemFood/api/system_food_api/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php",
        "line": 103,
        "args": []
    },
Med Karim Garali
  • 923
  • 1
  • 14
  • 37
  • weird. the only difference i noticed between your code and mine is the **@ApiSubResource** annotation and **fetch="EXTRA_LAZY"**. Can you try to put without ? Also, what happen when you update an additional field than __locations__? – rugolinifr Jul 27 '20 at 21:45
  • @rugolinifr OK I did it, and nothing change, the same error appears, and when I remove "client:put" group from location field, the request passes and the other fields than locations are updated correctly. – Med Karim Garali Jul 28 '20 at 10:38

1 Answers1

0

You need to add orphanRemoval=true and cascade={"persist", "remove"} to you locations variable in your Client entity

Salomon Zhang
  • 1,553
  • 3
  • 23
  • 41
Ziko10
  • 105
  • 1
  • 10