Skip to content

Proxy error when accessing unset fields without 'nullable: true' #2776

@TheVenon

Description

@TheVenon

Proxy error when accessing unset fields without nullable: true

Summary

After upgrading from Doctrine MongoDB ODM 1.2 to 2.10, I'm encountering a runtime error when accessing a field that is defined in the document class but is not present in some documents in the database (e.g., legacy documents created before the field existed).

The field is defined as:

#[Field(type: 'bool')]
protected $show_in_shop;

When accessing this field on a proxied document, I get the following error:

PHP Error: Undefined property: Proxies\__PM__\My\Document\ClassName\Generated123::$show_in_shop

This happens because ODM does not store the field when its value is null and nullable: true is not specified, so the field is $unset in MongoDB — as expected from the documentation:

"By default, ODM will $unset fields in MongoDB if the PHP value is null. Specify true for this option to force ODM to store a null value in the database instead of unsetting the field."

However, even though this behavior is expected, the proxy class still tries to access that property directly, which results in a error.

Expected behavior

I would expect the proxy or hydration system to handle missing (unset) fields gracefully, just like in ODM 1.2. Specifically, if a field is missing from the MongoDB document, it should default to null or a safe default — or at least not crash due to missing property on the proxy class.

Actual behavior

The proxy class throws a PHP error when the property is missing:

PHP Error: Undefined property: Proxies\__PM__\My\Document\ClassName\Generated123::$show_in_shop

Workaround

If I change the field definition to include nullable: true, the error goes away:

#[Field(type: 'bool', nullable: true)]
protected $show_in_shop;

This causes ODM to persist null into the database instead of unsetting the field. However, this seems to defeat the purpose of the default $unset behavior — and contradicts the documentation a bit, since proxies apparently still expect the property to exist.

Questions

  • Is this a regression from ODM 1.x or intended behavior in 2.x?

  • Should proxy classes be more tolerant to missing fields that were $unset?

  • Is nullable: true now required for all optional fields to avoid proxy errors?

Environment

  • PHP version: 8.4
  • Doctrine MongoDB ODM version: 2.11.2
  • MongoDB PHP driver: mongodb/mongodb ^2.0.0
  • MongoDB server version: 6.x

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions