Reputation: 75
I've got two entities mapped like this:
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;
...
}
and
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;
...
}
From unknown reason to me I'm getting message from Doctrine:
The association App\Entity\Email\EmailAddress#receivedEmail refers to the inverse side field App\Entity\Email\Email#recipients which does not exist.
What is wrong with my mapping? I really don't see any error. I've asked my colegues to check my code and they also don't see any problem. Strange thing is that relation sentEmail->senders is mapped according to doctrine right and it's working.
I've also tried to change OneToMany mapping to ManyToMany like this but I've still got same error.
EDIT 1:
Date in database: Table email
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
Upvotes: 0
Views: 149
Reputation: 48893
This question/answer probably follows under the heading of a 'typo' but I thought it might be interesting to discuss.
The problem is here:
/***
* @var Collection|EmailAddress[]
* @ORM\OneToMany(targetEntity="App\Entity\Email\EmailAddress", mappedBy="receivedEmail", cascade={"all"}, orphanRemoval=true)
*/
private ?Collection $recipients = null;
The extra asterisk /*** in the annotation block opening caused the recipients property to be skipped by Doctrine. But everything still seemed to be okay. The database tables and indexes were all generated as expected.
I made a simple console command to insert an email entity and quickly noticed that the sender address was inserted but not the recipient address. Triple checked the various methods but still no go. Explicitly persisting the address worked but the cascade option should have taken care of that. And of course retrieving the recipient address was not working even after an entity was inserted.
At some point I noticed the /*** and changed it to /** and everything worked as expected. Using a console command to test helped quite a bit as opposed to refreshing a browser and hunting around in the debug bar.
On the plus side, if you ever need to temporarily remove an annotation then just adding an asterisk is basically the same as commenting it out.
Upvotes: 1