Home > Net >  Symfony MongoDb default sets empty array instead of not setting field
Symfony MongoDb default sets empty array instead of not setting field

Time:11-06

I've got a Document class with an EmbeddedDocument multiple self-inherited. It's working fine, but when i'm not sending subData it's saved in Mongo as empty array (subData: []).

I would expect that this field isn't saved at all if not sent.

I've tried with nullable=false and nullable=true.

Not setting ArrayCollection in __construct makes error Call to a member function add() on null

  • Symfony 4.3
  • doctrine/mongodb 1.6.4
  • doctrine/mongodb-odm 1.3.7
  • doctrine/mongodb-odm-bundle 3.6.2
<?php

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @MongoDB\EmbeddedDocument()
 */
class Data
{
    /**
     * @MongoDB\Id()
     */
    private $id;

    /**
     * @MongoDB\Field(type="string")
     */
    private $value;

    /**
     * @MongoDB\EmbedMany(targetDocument="App\Document\Data", nullable=false)
     */
    public $subData = null;

    public function __construct()
    {
        $this->subData = new ArrayCollection();
    }

    public function getId(): ?string
    {
        return $this->id;
    }

    public function getValue(): ?string
    {
        return $this->value;
    }

    public function setValue(string $value): self
    {
        $this->value = $value;

        return $this;
    }

    public function getSubData(): Collection
    {
        return $this->subData;
    }

    public function setSubData(array $subData): self
    {
        $this->subData = $subData;

        return $this;
    }

    public function addSubdata(Data $subData): self
    {
        $this->subData->add($subData);

        return $this;
    }
}

UPDATED

changing setter to this didn't help as suggest @Maniax it's still subData: []

    public function setSubData(array $subData): self
    {
        if(!empty($subData) && count($subData) > 0 && $subData !== null) {
            $this->subData = $subData;
        }

        return $this;
    }

CodePudding user response:

If you don't want null in you database when the array is empty, you want to avoid initializing it by default, so avoid

public function __construct()
{
    $this->subData = new ArrayCollection();
}

The array still needs to be initialized, so in the add function you'll have to check if the array is not initialized before adding

public function addSubData(Data $subData): self
{
    // null and an empty array are falsey
    if (!$this->subData) {
        $this->subData = new ArrayCollection();
    }
    $this->subData->add($subData);
}

return $this;
}

And in the setter you check if you're not getting an empty array

public function setSubData(array $subData): self
{
    if(!empty($subData)) {
        $this->subData = $subData;
    }

    return $this;
}

This should prevent an empty array to end up in your database.

  • Related