PHPackages                             wazum/nullable-embeddable-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. wazum/nullable-embeddable-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

wazum/nullable-embeddable-bundle
================================

Symfony bundle for handling nullable Doctrine embeddables

1.0.0(1y ago)161MITPHPPHP &gt;=8.1

Since Dec 21Pushed 1y ago1 watchersCompare

[ Source](https://github.com/wazum/nullable-embeddable-bundle)[ Packagist](https://packagist.org/packages/wazum/nullable-embeddable-bundle)[ RSS](/packages/wazum-nullable-embeddable-bundle/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

Nullable Embeddable Bundle
==========================

[](#nullable-embeddable-bundle)

[![CI](https://github.com/wazum/nullable-embeddable-bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/wazum/nullable-embeddable-bundle/actions/workflows/ci.yml)

A [Symfony bundle](https://symfony.com/doc/current/bundles.html) that provides support for nullable [*Doctrine Embeddables*](https://www.doctrine-project.org/projects/doctrine-orm/en/3.3/tutorials/embeddables.html). It allows embeddable objects to become `null` when all their properties are `null`, providing a cleaner way to handle optional embedded values.

Installation
------------

[](#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
-----

[](#usage)

### 1. Create your embeddable class

[](#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

[](#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)

[](#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

[](#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

[](#3-configuration)

The bundle will automatically register its Doctrine event subscriber. No additional configuration is required.

How It Works
------------

[](#how-it-works)

The bundle uses a [Doctrine event subscriber](https://www.doctrine-project.org/projects/doctrine-orm/en/3.3/reference/events.html#reference-events-post-load) 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 after `refresh()` has been applied to it.

### Example

[](#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
--------

[](#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](https://www.doctrine-project.org/projects/doctrine-orm/en/3.3/tutorials/embeddables.html)
- Supports both PHP attribute and XML mapping configurations
- Type-safe through PHP 8 features

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues

[](#common-issues)

- Embeddable not becoming `null`:

    - Verify the entity has the `#[ContainsNullableEmbeddable]` attribute
    - Verify the property has a nullable type (`?` or `null` type) *or* has the `#[NullableEmbedded]` attribute set
    - Check that all properties in the embeddable are actually `null`
- Type errors:

    - Ensure your embeddable properties are nullable (`?type`)
    - Ensure your entity's embeddable property is nullable

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run all checks (CS Fixer, Psalm, and PHPUnit):

```
composer check-all
```

License
-------

[](#license)

This bundle is released under the MIT License. See the [LICENSE](LICENSE) file for details.

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

###  Health Score

26

—

LowBetter than 40% of packages

Maintenance35

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

604d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f4ea950f22b43e010ba4f0a6effb0928a6a1d11f64d36cec0d030b757bdfa85e?d=identicon)[wazum](/maintainers/wazum)

---

Top Contributors

[![wazum](https://avatars.githubusercontent.com/u/146727?v=4)](https://github.com/wazum "wazum (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/wazum-nullable-embeddable-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/wazum-nullable-embeddable-bundle/health.svg)](https://phpackages.com/packages/wazum-nullable-embeddable-bundle)
```

###  Alternatives

[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

12017.1k](/packages/rcsofttech-audit-trail-bundle)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k18.3M430](/packages/easycorp-easyadmin-bundle)[kimai/kimai

Kimai - Time Tracking

4.8k9.4k1](/packages/kimai-kimai)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1617.3k16](/packages/2lenet-crudit-bundle)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.9M535](/packages/pimcore-pimcore)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M235](/packages/sulu-sulu)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
