maker-bundle icon indicating copy to clipboard operation
maker-bundle copied to clipboard

Drop nullable-question for `simple_array`, `array` and `json`?

Open ThomasLandauer opened this issue 5 years ago • 5 comments
trafficstars

When answering "yes" to the nullable-question ("Can this field be null in the database (nullable)"), the result is:

/**
 * @ORM\Column(type="json", nullable=true)
 */
private $col1 = [];

/**
 * @ORM\Column(type="simple_array", nullable=true)
 */
private $col2 = [];

/**
 * @ORM\Column(type="array", nullable=true)
 */
private $col3 = [];

But if each new entity is instantiated with an empty array ([]), I only see two ways how this could ever be null in the database:

  • You set it to null yourself, explicitly: (new Foo())->setCol1(null)
  • You enter it manually in the database, without Doctrine

Both seem to be "special" cases. So I'm wondering if it wouldn't be better to omit the nullable-question for these types, and just silently default to non-nullable - requiring those few people who need this, to manually add it.

ThomasLandauer avatar Oct 03 '20 15:10 ThomasLandauer

That makes sense to me. In my apps, I would never try to set one of these fields to null, I would initialize you an empty array. We should avoid nullable on these, it’s pointless

weaverryan avatar Oct 04 '20 21:10 weaverryan

Hold on, I missed something here! When answering "no" (=default!) to the nullable question, I'm getting:

/**
 * @ORM\Column(type="simple_array")
 */
private $bar = [];
public function getBar(): ?array
{
    return $this->bar;
}
public function setBar(array $bar): self
{
    $this->bar = $bar;
    return $this;
}

But then, when trying to persist $foo = new Foo(), Doctrine gives this error:

An exception occurred while executing 'INSERT INTO foo (bar) VALUES (?)' with params [null]: SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: foo.bar

So it looks like [] is converted to null when persisting.

@weaverryan How do you deal with this?

ThomasLandauer avatar Oct 13 '20 13:10 ThomasLandauer

Hmm. This sounds like it is a potential Doctrine issue. IIRC the preferred way by Doctrine to set a default value for a property is using the property it self - as referenced in the above code snippet. We should probably dig a little bit deeper into doctrine types + any gotcha's for those types.

But in the meantime, what version of Symfony & Doctrine are you using in the code snippet above @ThomasLandauer

jrushlow avatar Oct 27 '20 17:10 jrushlow

Symfony 4.4 and doctrine/orm 2.7.4

ThomasLandauer avatar Oct 28 '20 12:10 ThomasLandauer

Doctrine's mapping is a bit confusing with this type(s). I tried to drop the nullable: true from the config of a simple_array type but then got a "not null violation" when trying to save an entity with an empty array.

The documentation doesn't say much :

Values retrieved from the database are always converted to PHP's array type using comma delimited explode() or null if no data is present.

The only bit of information I found (besides this issue) is this old one (still open) :

https://github.com/doctrine/orm/issues/4673

Leading to this issue which won't be fixed because of BC break :

https://github.com/doctrine/dbal/pull/877

So I guess it's better to always use nullable: true for this type and deal with a nullable entity property in the code. :smiling_face_with_tear:

Brewal avatar Jul 24 '23 14:07 Brewal