Symfony - Doctrine - How to set one-to-one relation with field not exist in target table, but exist in another one

Today, I faced with a bug:

  • Custom Field entity has a RelId column relates to two different entities: Product and Bundle.
  • Set RelId into Custom Field directly connected to Product, but not exist in Bundle table.
  • After Entity Manager flush(), I got an error: RelId can not be null.

How come that RelId field became null, when flushing.

After debugging, I realized, Doctrine checks if exist this connected RelId field in Bundle table. If not, Doctrine just set RelId to null and go on.

So, we need not to set RelId directly, but using entity, like Product or Bundle, in my case.

Here's a simplified example using annotations:

Let's assume you have three entities: SourceEntity, TargetEntity, and RelationEntity. RelationEntity will act as the join table, holding the relationship between SourceEntity and TargetEntity.


// SourceEntity.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class SourceEntity
{
    // ... other properties

    /**
     * @ORM\OneToOne(targetEntity="RelationEntity", mappedBy="source")
     */
    private $relation;
}

// TargetEntity.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class TargetEntity
{
    // ... other properties

    /**
     * @ORM\OneToOne(targetEntity="RelationEntity", mappedBy="target")
     */
    private $relation;
}

// RelationEntity.php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class RelationEntity
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="SourceEntity", inversedBy="relation")
     * @ORM\JoinColumn(name="source_id", referencedColumnName="id")
     */
    private $source;

    /**
     * @ORM\OneToOne(targetEntity="TargetEntity", inversedBy="relation")
     * @ORM\JoinColumn(name="target_id", referencedColumnName="id")
     */
    private $target;
}

In this example, RelationEntity serves as a join table with two one-to-one relationships pointing to SourceEntity and TargetEntity. The JoinColumn annotations specify the columns in the RelationEntity table that represent the foreign keys for the relationship.

Comments

Popular posts from this blog

CSS Как прикрепить слой (div) к краю

MySQL - How to add JSON column type

Как сделать заголовок модуля активной ссылкой в Joomla 1.5