I'm doing a user registration. I have two entities: User, UserCredential
#[Entity, Table(name: 'user')]
#[HasLifecycleCallbacks]
class UserEntity implements JsonSerializable
{
const INACTIVE = 0;
const ACTIVE = 1;
const BLOCKED = 2;
const IS_DELETED_NO = 0;
const IS_DELETED_YES = 1;
#[Id, Column(type: Types::INTEGER), GeneratedValue(strategy: 'AUTO')]
private int $id;
#[Column(name: 'role_id', type: Types::INTEGER, length: 11, options: ['default' => 0])]
private int $roleId;
#[Column(name: 'email', type: Types::STRING, length: 255, unique: true, nullable: false)]
private string $email;
#[Column(name: 'status', type: Types::SMALLINT, options: ['default' => self::INACTIVE])]
private int $status = self::INACTIVE;
#[Column(name: 'created_at', type: Types::INTEGER, length: 11)]
private int $createdAt;
#[Column(name: 'updated_at', type: Types::INTEGER, length: 11)]
private int $updatedAt;
#[Column(name: 'is_deleted', type: Types::SMALLINT, options: ['default' => self::IS_DELETED_NO])]
private int $isDeleted = self::IS_DELETED_NO;
#[OneToOne(mappedBy: 'user', targetEntity: UserCredentialEntity::class)]
private UserCredentialEntity $credential;
....
#[Entity, Table(name: 'user_credential')]
class UserCredentialEntity
{
#[Id, Column(type: Types::INTEGER), GeneratedValue(strategy: 'AUTO')]
private int $id;
#[Column(name: 'user_id', type: Types::INTEGER, length: 11)]
private int $userId;
#[Column(name: 'password_hash', type: Types::STRING, length: 255, nullable: false)]
private string $passwordHash;
#[Column(name: 'email_confirm_key', type: Types::STRING, length: 255, nullable: true)]
private ?string $emailConfirmKey = null;
#[OneToOne(targetEntity: UserEntity::class)]
#[JoinColumn(name: 'user_id', referencedColumnName: 'id')]
private UserEntity $user;
public function __construct(UserEntity $user, string $password)
{
//$this->userId = $user->getId();
$this->user = $user;
$this->passwordHash = $password;
}
}
public function createUser(string $email, string $password): User | Exception
{
$this->em->getConnection()->beginTransaction();
try {
$user = new User($email);
$user->setRoleId(1);
$this->em->persist($user);
$userCredential = new UserCredentialEntity($user, 'password');
$this->em->persist($userCredential);
$this->em->flush();
$this->em->getConnection()->commit();
return $user;
} catch (Exception $e) {
var_dump($e->getMessage());
$this->em->getConnection()->rollback();
throw $e;
}
}
How to make the UserCredential entity be saved automatically with the required User id?
I'm getting an error:
"An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null"
Why would you have two references to the User in the UserCredentials?
In the User entity
#[OneToOne(mappedBy: 'user', targetEntity: UserCredentialEntity::class)]
private UserCredentialEntity $credential;
In the UserCredentials entity
Remove the $userId in this class because you can already get it from the $user.
#[OneToOne(inversedBy: 'credential', targetEntity: UserEntity::class)]
private UserEntity $user;