Doctrine 中的 OneToMany 和 ManyToOne 关系 - 奇怪的映射错误
OneToMany and ManyToOne relation in Doctrine - strange mapping error
我有两个实体映射如下:
namespace App\Entity\Email;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface;
use Knp\DoctrineBehaviors\Model\Blameable\BlameableTrait;
use Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletableTrait;
use Knp\DoctrineBehaviors\Model\Timestampable\TimestampableTrait;
/**
* @ORM\Entity(repositoryClass="App\Repository\Email\EmailRepository")
*/
class Email implements SoftDeletableInterface, TimestampableInterface, BlameableInterface
{
use SoftDeletableTrait;
use TimestampableTrait;
use BlameableTrait;
/**
* @ORM\Column(type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private ?int $id = null;
...
/**
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="sentEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $senders = null;
/***
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="receivedEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $recipients = null;
...
}
和
namespace App\Entity\Email;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface;
use Knp\DoctrineBehaviors\Model\Blameable\BlameableTrait;
use Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletableTrait;
use Knp\DoctrineBehaviors\Model\Timestampable\TimestampableTrait;
/**
* @ORM\Entity()
*/
class EmailAddress implements SoftDeletableInterface, TimestampableInterface, BlameableInterface
{
use SoftDeletableTrait;
use TimestampableTrait;
use BlameableTrait;
/**
* @ORM\Column(type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private ?int $id = null;
...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Email\Email", inversedBy="senders")
* @ORM\JoinColumn()
*/
private ?Email $sentEmail = null;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Email\Email", inversedBy="recipients")
* @ORM\JoinColumn()
*/
private ?Email $receivedEmail = null;
...
}
出于未知原因,我收到了来自 Doctrine 的消息:
The association App\Entity\Email\EmailAddress#receivedEmail refers to the inverse side field App\Entity\Email\Email#recipients which does not exist.
我的映射有什么问题?我真的没有看到任何错误。我已经让我的同事检查我的代码,他们也没有发现任何问题。奇怪的是,关系 sentEmail->senders 是根据正确的原则映射的,并且它正在工作。
我也试过像 this 那样将 OneToMany 映射更改为 ManyToMany,但我仍然遇到同样的错误。
编辑 1:
数据库中的日期:
Table 电子邮件
id | created_by_id | updated_by_id | deleted_by_id | deleted_at | created_at | updated_at | subject | content
1 | NULL | NULL | NULL | NULL | 1616156920 | 1616156920 | Test | Test
Table email_address
id | created_by_id | updated_by_id | deleted_by_id | address | deleted_at | created_at | updated_at | sent_email_id | received_email_id
1 | NULL | NULL | NULL | test1@test.com | NULL | 1616156920 | 1616156920 | NULL | 1
2 | NULL | NULL | NULL | test2@test.com | NULL | 1616156920 | 1616156920 | 1 | NULL
这个 question/answer 可能在 'typo' 的标题下,但我认为讨论它可能会很有趣。
问题出在这里:
/***
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="receivedEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $recipients = null;
注释块开头的额外星号 /*** 导致收件人 属性 被 Doctrine 跳过。但一切似乎都还好。数据库表和索引都按预期生成了。
我做了一个简单的控制台命令来插入一个电子邮件实体,并很快注意到插入了发件人地址而不是收件人地址。三次检查了各种方法,但仍然没有成功。明确保留地址有效,但级联选项应该已经解决了这个问题。当然,即使在插入实体后检索收件人地址也无法正常工作。
在某些时候我注意到 /*** 并将其更改为 /** 并且一切都按预期进行。使用控制台命令进行测试比刷新浏览器并在调试栏中四处寻找更有帮助。
从好的方面来说,如果您需要临时删除注释,那么只需添加一个星号与将其注释掉基本上是一样的。
我有两个实体映射如下:
namespace App\Entity\Email;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface;
use Knp\DoctrineBehaviors\Model\Blameable\BlameableTrait;
use Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletableTrait;
use Knp\DoctrineBehaviors\Model\Timestampable\TimestampableTrait;
/**
* @ORM\Entity(repositoryClass="App\Repository\Email\EmailRepository")
*/
class Email implements SoftDeletableInterface, TimestampableInterface, BlameableInterface
{
use SoftDeletableTrait;
use TimestampableTrait;
use BlameableTrait;
/**
* @ORM\Column(type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private ?int $id = null;
...
/**
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="sentEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $senders = null;
/***
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="receivedEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $recipients = null;
...
}
和
namespace App\Entity\Email;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface;
use Knp\DoctrineBehaviors\Model\Blameable\BlameableTrait;
use Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletableTrait;
use Knp\DoctrineBehaviors\Model\Timestampable\TimestampableTrait;
/**
* @ORM\Entity()
*/
class EmailAddress implements SoftDeletableInterface, TimestampableInterface, BlameableInterface
{
use SoftDeletableTrait;
use TimestampableTrait;
use BlameableTrait;
/**
* @ORM\Column(type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private ?int $id = null;
...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Email\Email", inversedBy="senders")
* @ORM\JoinColumn()
*/
private ?Email $sentEmail = null;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Email\Email", inversedBy="recipients")
* @ORM\JoinColumn()
*/
private ?Email $receivedEmail = null;
...
}
出于未知原因,我收到了来自 Doctrine 的消息:
The association App\Entity\Email\EmailAddress#receivedEmail refers to the inverse side field App\Entity\Email\Email#recipients which does not exist.
我的映射有什么问题?我真的没有看到任何错误。我已经让我的同事检查我的代码,他们也没有发现任何问题。奇怪的是,关系 sentEmail->senders 是根据正确的原则映射的,并且它正在工作。
我也试过像 this 那样将 OneToMany 映射更改为 ManyToMany,但我仍然遇到同样的错误。
编辑 1:
数据库中的日期: Table 电子邮件
id | created_by_id | updated_by_id | deleted_by_id | deleted_at | created_at | updated_at | subject | content
1 | NULL | NULL | NULL | NULL | 1616156920 | 1616156920 | Test | Test
Table email_address
id | created_by_id | updated_by_id | deleted_by_id | address | deleted_at | created_at | updated_at | sent_email_id | received_email_id
1 | NULL | NULL | NULL | test1@test.com | NULL | 1616156920 | 1616156920 | NULL | 1
2 | NULL | NULL | NULL | test2@test.com | NULL | 1616156920 | 1616156920 | 1 | NULL
这个 question/answer 可能在 'typo' 的标题下,但我认为讨论它可能会很有趣。
问题出在这里:
/***
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="receivedEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $recipients = null;
注释块开头的额外星号 /*** 导致收件人 属性 被 Doctrine 跳过。但一切似乎都还好。数据库表和索引都按预期生成了。
我做了一个简单的控制台命令来插入一个电子邮件实体,并很快注意到插入了发件人地址而不是收件人地址。三次检查了各种方法,但仍然没有成功。明确保留地址有效,但级联选项应该已经解决了这个问题。当然,即使在插入实体后检索收件人地址也无法正常工作。
在某些时候我注意到 /*** 并将其更改为 /** 并且一切都按预期进行。使用控制台命令进行测试比刷新浏览器并在调试栏中四处寻找更有帮助。
从好的方面来说,如果您需要临时删除注释,那么只需添加一个星号与将其注释掉基本上是一样的。