Skip to content

EntityExists

Edit this page

Validates that a value references an existing Doctrine entity. This is typically used on identifiers received in DTOs or API payloads, to replace the repetitive "find the entity, check it's not null, throw an exception" logic with a regular validation violation.

Note

In order to use this constraint, you should have installed the symfony/doctrine-bridge with Composer.

8.2

The EntityExists constraint was introduced in Symfony 8.2.

Basic Usage

Suppose a command object stores the identifier of the User entity it refers to. Use the EntityExists constraint to ensure that a User with that identifier exists in the database:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Command/AssignUserCommand.php
namespace App\Command;

use App\Entity\User;
use Symfony\Bridge\Doctrine\Validator\Constraints\EntityExists;
use Symfony\Component\Validator\Constraints as Assert;

final class AssignUserCommand
{
    #[Assert\NotBlank]
    #[EntityExists(entityClass: User::class)]
    public int $userId;
}

By default, the value is looked up by the single identifier field of the entity, using the findOneBy() method of its repository. The entity loaded during validation is kept in Doctrine's identity map, so fetching it again later with find() doesn't trigger a second query.

Note

As with most constraints, null and empty strings are considered valid values. Combine it with NotBlank, as in the example above, when the value is required.

Options

em

type: string default: null

The name of the entity manager to use to look the entity up. If it's left blank, the entity manager is resolved from the entityClass option. For that reason, this option should probably not need to be used.

entityClass

type: string

This required option is the fully-qualified class name (FQCN) of the Doctrine entity to look up.

groups

type: array | string default: null

It defines the validation group or groups of this constraint. Read more about validation groups.

identifierField

type: string default: null

By default, the value is looked up by the identifier field of the entity. Use this option to look it up by another field or association instead (e.g. a slug or an email field). This option is required when the entity has a composite identifier.

This option can't be combined with the repositoryMethod option.

invalidMessage

type: string default: This value is not valid.

The message shown when the value can't be converted to the type of the field used for the lookup (e.g. a malformed UUID for a uuid field).

You can use the following parameters in this message:

Parameter Description
{{ value }} The current (invalid) value

message

type: string default: The referenced entity does not exist.

The message shown when no entity matches the value.

You can use the following parameters in this message:

Parameter Description
{{ value }} The current (invalid) value

payload

type: mixed default: null

This option can be used to attach arbitrary domain-specific data to a constraint. The configured payload is not used by the Validator component, but its processing is completely up to you.

For example, you may want to use several error levels to present failed constraints differently in the front-end depending on the severity of the error.

repositoryMethod

type: string default: null

The name of a method of the entity repository to call instead of findOneBy(). The method receives the validated value as its only argument and the entity is considered to exist when the method returns a truthy value. The return value is not used otherwise, so the method can return anything: an entity, a count, a boolean, etc. This is useful, for example, to run a lightweight COUNT() query and avoid hydrating the entity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/Repository/UserRepository.php
namespace App\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;

class UserRepository extends ServiceEntityRepository
{
    // ...

    public function existsWithActiveSubscription(int $id): bool
    {
        return 0 < $this->createQueryBuilder('u')
            ->select('COUNT(u.id)')
            ->andWhere('u.id = :id')
            ->andWhere('u.subscriptionEndsAt > CURRENT_TIMESTAMP()')
            ->setParameter('id', $id)
            ->getQuery()
            ->getSingleScalarResult();
    }
}
1
2
3
4
5
6
7
8
9
10
11
// src/Command/AssignUserCommand.php
namespace App\Command;

use App\Entity\User;
use Symfony\Bridge\Doctrine\Validator\Constraints\EntityExists;

final class AssignUserCommand
{
    #[EntityExists(entityClass: User::class, repositoryMethod: 'existsWithActiveSubscription')]
    public int $userId;
}

This option can't be combined with the identifierField option.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version