На Symfony4 я использую Ambta \ DoctrineEncryptBundle для шифрования некоторых столбцов в моей БД.
Функционально, все работает нормально, но журналы показывают, что при выборе объекта, если есть грипп sh где-то тогда сущность обновляется новыми значениями в зашифрованных столбцах (простые данные не меняются, так что это просто проблема производительности: он не должен обновлять то, что не изменилось).
Вот пример функция, которая ничего не делает, кроме запроса сущности User (данные для аутентификации), которая связана с сущностью Identity (имя корпуса / имя пользователя).
/**
* @Route("/myaccount2/", name="myAccount2", methods={"GET", "POST"})
* @IsGranted("ROLE_USER")
*/
public function myAccount2(LoggerInterface $logger)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$logger->debug('before');
$em->flush();
$logger->debug('after');
return $this->redirectToRoute('index');
}
Это не должно делать ничего в БД, но журналы показывают это:
[2020-05-07 09:42:14] app.DEBUG: before [] []
[2020-05-07 09:42:14] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-05-07 09:42:14] doctrine.DEBUG: UPDATE identity SET name = ?, given_name = ? WHERE id = ? ["MUIEAAYnaoFEu3KQ1Y-HH6XfRb [...]","MUIEADmhmrmQJgV-ITjZymLS-- [...]","a8c39458-8213-4534-9767-57 [...]"] []
[2020-05-07 09:42:14] doctrine.DEBUG: "COMMIT" [] []
[2020-05-07 09:42:14] app.DEBUG: after [] []
И взгляд на БД показывает, что соответствующие значения фактически обновлены.
Вот части определения задействованных сущностей:
Пользователь
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity(fields={"email"}, message="security.alreadyused")
*/
class User implements UserInterface
{
/**
* @ORM\OneToOne(targetEntity="App\Entity\Identity", mappedBy="User", cascade={"persist", "remove"})
*/
private $identity;
Идентификация
<?php
namespace App\Entity;
use Ambta\DoctrineEncryptBundle\Configuration\Encrypted;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\IdentityRepository")
* @UniqueEntity(
* fields={"alias"},
* message="public.alias.unique"
* ))
*/
class Identity
{
/**
* @ORM\Id()
* @ORM\Column(type="string", length=36, nullable=false)
*/
private $id;
/**
* @ORM\Column(type="string", length=1000)
* @Encrypted
*/
private $name;
/**
* @ORM\Column(type="string", length=1000)
* @Encrypted
*/
private $givenName;
/**
* @ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="identity", cascade={"persist", "remove"})
* @ORM\JoinColumn(nullable=false)
*/
private $User;
Обратите внимание, что если @encrypted удаляется из двух полей (имя и имя enName) в сущности Identity, БД не обновляется:
[2020-05-07 11:06:18] app.DEBUG: before [] []
[2020-05-07 11:06:18] app.DEBUG: after [] []
Спасибо за понимание этого странного поведения!