wazum / nullable-embeddable-bundle
Symfony bundle for handling nullable Doctrine embeddables
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=8.1
- doctrine/doctrine-bundle: ^2.11
- doctrine/orm: ^2.14 || ^3.0
- symfony/framework-bundle: ^6.4 || ^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.65
- phpunit/phpunit: ^10.5 || ^11.5
- symfony/test-pack: ^1.0
- vimeo/psalm: 6.x-dev
README
A Symfony bundle that provides support for nullable Doctrine Embeddables. It allows embeddable objects to become null
when all their properties are null
, providing a cleaner way to handle optional embedded values.
Installation
Install the bundle using Composer:
composer require wazum/nullable-embeddable-bundle
The bundle supports:
- PHP 8.1 or higher
- Symfony 6.4 or 7.0 or higher
- Doctrine ORM 2.14 or 3.0 or higher
Usage
1. Create your embeddable class
Create a standard Doctrine embeddable class:
use Doctrine\ORM\Mapping as ORM; #[ORM\Embeddable] final class EmailAddress { #[ORM\Column(type: 'string', length: 255, nullable: true)] public readonly ?string $address = null; // ... constructor and methods }
2. Set up the containing entity
First, add the #[ContainsNullableEmbeddable]
attribute to your entity. Then, you have two options to make an embeddable property nullable:
Option 1: Using PHP type hints (recommended)
Simply declare the embeddable property with a nullable type hint (?
or null
type):
use Wazum\NullableEmbeddableBundle\Attribute\ContainsNullableEmbeddable; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ContainsNullableEmbeddable] class User { #[ORM\Embedded(class: EmailAddress::class)] private ?EmailAddress $emailAddress = null; // ... constructor and methods }
Option 2: Using the custom NullableEmbedded
attribute
For properties without type hints or when you need to explicitly mark an embeddable as nullable:
use Wazum\NullableEmbeddableBundle\Attribute\ContainsNullableEmbeddable; use Wazum\NullableEmbeddableBundle\Attribute\NullableEmbedded; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ContainsNullableEmbeddable] class User { #[ORM\Embedded(class: EmailAddress::class)] #[NullableEmbedded] private $emailAddress = null; // ... constructor and methods }
You can choose either approach based on your needs. Using PHP type hints is recommended as it provides better type safety and IDE support.
3. Configuration
The bundle will automatically register its Doctrine event subscriber. No additional configuration is required.
How It Works
The bundle uses a Doctrine event subscriber that listens to the postLoad
event. When an entity marked with #[ContainsNullableEmbeddable]
is loaded, the subscriber checks its embedded properties that either have a nullable type hint or are marked with the #[NullableEmbedded]
attribute. If an embeddable property has all its values set to null
, the entire embeddable is set to null
.
The
postLoad
event occurs after the entity has been loaded into the current EntityManager from the database or afterrefresh()
has been applied to it.
Example
$user = new User( emailAddress: new EmailAddress(address: null) ); $entityManager->persist($user); $entityManager->flush(); $entityManager->clear(); // When reloading: $user = $entityManager->find(User::class, $user->getId()); $user->getEmailAddress(); // Returns null, not an EmailAddress instance with null values
Features
- Zero configuration required: Just add the attribute(s), set type hints and it works
- Automatically converts empty embeddable objects to null during database loads (instead of keeping objects with all-null properties)
- Fine-grained control: Mark only the properties you want to be nullable
- Works with any Doctrine Embeddable
- Supports both PHP attribute and XML mapping configurations
- Type-safe through PHP 8 features
Troubleshooting
Common Issues
-
Embeddable not becoming
null
:- Verify the entity has the
#[ContainsNullableEmbeddable]
attribute - Verify the property has a nullable type (
?
ornull
type) or has the#[NullableEmbedded]
attribute set - Check that all properties in the embeddable are actually
null
- Verify the entity has the
-
Type errors:
- Ensure your embeddable properties are nullable (
?type
) - Ensure your entity's embeddable property is nullable
- Ensure your embeddable properties are nullable (
Testing
Run the test suite:
composer test
Run all checks (CS Fixer, Psalm, and PHPUnit):
composer check-all
License
This bundle is released under the MIT License. See the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.