New in Symfony 7.1: Expanding UniqueEntity Constraint to Any PHP Class
Contributed by
Wojciech Kania
in #38662.
In Symfony applications, the UniqueEntity constraint validates that some field
(or fields) in a Doctrine entity is (are) unique. This is useful for example to
prevent a new user to register using an email address that already exists in the system.
In Symfony 7.1, we’re improving this constraint to also check uniqueness on any
PHP class (e.g. DTOs) and not only on Doctrine entities. Consider the following
Doctrine entity:
// src/Entity/User.php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
class User
{
#[ORMColumn(type: ’string‘)]
public string $id;
#[ORMColumn(type: ’string‘)]
public string $username;
}
Instead of adding the UniqueEntity constraint to it, you can now check for
uniqueness in other ways. For example, in a Messenger component message that
creates User entities, you can now define the following:
namespace AppMessage;
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
#[UniqueEntity(fields: [‚username‘], entityClass: User::class)]
class HireAnEmployee
{
public function __construct(
private string $username
) {
}
}
Although the HireAnEmployee class is not a Doctrine entity, this constraint
will effectively check that the given username value is unique for the User
Doctrine class.
If the names of the unique properties in this class are different from the
Doctrine entity property names, you can map them:
#[UniqueEntity(
// ‚userIdentifier‘ is the property name in the PHP class and
// ‚username‘ is the property name in the Doctrine entity
fields: [‚userIdentifier‘ => ‚username‘],
entityClass: User::class,
)]
When updating an entity, use the identifierFieldNames option to define the
class properties that are used as the Doctrine entity key (or composite key):
namespace AppMessage;
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
#[UniqueEntity(
fields: [’name‘],
entityClass: User::class,
// ‚uid‘ is the property name in the PHP class and ‚id‘ is the name of
// the Doctrine entity property used as the primary key
identifierFieldNames: [‚uid‘ => ‚id‘],
)]
class UpdateEmployeeProfile
{
public function __construct(
private string $uid,
private string $name,
) {
}
}
Symfony Blog