symfony - 在持久化数据之后和刷新数据之前触发 UniqueEntity
问题描述
我正在通过学说实体管理器导入一种 csv 数据,但是,我有一个执行批处理的循环,正如在文档级别提到的那样。 https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/batch-processing.html#bulk-inserts
$validationErrors = [];
foreach($data as $itrationNumber => $item) {
/** @var User|null $user **/
$user = $this->em->getRepository(User::class)->findOnBy(['email' => $item['email']]);
$user = ($user) ? $user : new User();
$user->setName('test');
$errors = $this->validator->validate($user);
if ($errors->count() === 0) {
$this->persist($user);
} else {
$validationErrors[] = $errors;
}
if ($itratioNumber% 100 === 0) {
$this->em->flush();
}
}
return $validationErrors;
这是我的用户类,它对电子邮件字段有一个独特的约束:
/**
* @ORM\Entity
* @UniqueEntity("email")
*/
class User
{
/**
* @ORM\Column(name="email", type="string", length=255, unique=true)
* @Assert\Email
*/
protected $email;
}
不幸的是,如果我的数据中有不止一行具有相同的电子邮件地址,UniqueEntity
则不会触发验证,原因很简单,因为用户被持久化但没有被刷新到数据库中。
- 解决方案 1:避免批处理并在每次迭代时进行刷新,这非常违反并且可能引发连接关闭原则或某种内存泄漏。
- 解决方案 2:它是创建一个自定义约束,其灵感来自
UniqueEntity("email")
然后检查每个项目的电子邮件地址,如果有用户已经使用相同的邮件持久化。
如果用户已经存在于数据库中,并且我们调用 的问题,我在和 中
em-> persist()
都找不到任何持久对象。$entityManager->getUnitOfWork()->getScheduledEntityInsertions()
$entityManager->getUnitOfWork()->getScheduledEntityUpdates()
仅在新插入期间,我洞对象在函数的响应中持续存在->getScheduledEntityInsertions()
如果有人知道如何恢复$entityManager->persist()
步骤后仍然存在的实体,我将不胜感激。或者只是第三种解决方案,即使在批处理上下文中,它也允许我触发对电子邮件唯一性的验证。
解决方案
您应该保留第二点信息,以查看电子邮件地址是否已被处理:
$emails = [];
foreach($data as $itrationNumber => $item) {
if (isset($emails[$item['email']])) {
continue;
}
/** @var User|null $user **/
$user = $this->em->getRepository(User::class)->findOnBy(['email' => $item['email']]);
$user = ($user) ? $user : new User();
$user->setName('test');
if ($this->validator->validate($user)->count() === 0) {
$this->persist($user);
$emails[$item['email']] = true;
}
if ($itratioNumber% 100 === 0) {
$this->em->flush();
}
}
此代码片段不会规范化电子邮件地址,这应该首先完成(例如 strtolower 并且可能删除 +foo gmail 本地部分)。
推荐阅读
- reactjs - 在 React 中渲染来自 Firebase Firestore 的数据
- c++ - 如何让这个打印到outfile?(c++)
- android - java.lang.ClassCastException:com.example.readdoang.ui.login_regist_activity.LoginRegistActivity 无法转换为 com
- javascript - 如何使 React 组件可以访问并且需要异步数据才能使用的变量?
- php - 如何修复此错误 Undefined offset: 1 in line 178
- c++ - 预提交时cpp中的memleak
- ruby-on-rails - 如何为 API 版本化模型验证?
- amazon-ec2 - 设置 Github 操作以在 EC2 上构建和部署 java 代码
- java - 为什么我不能从本地存储库导入 maven jar?
- tensorflow - Rasa 训练数据集