Doctrine2 - 如何改变拥有方,如何设置不为null

问题描述:

I have such relation:

class TaskSet
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;


    /**
     * @var \Doctrine\Common\Collections\ArrayCollection $tasks
     *
     * @ORM\OneToMany (targetEntity="Task", mappedBy="taskset", cascade={"ALL"})
     */
    private $tasks;

and

class Task
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var TaskSet $taskset
     *
     * @ORM\ManyToOne(targetEntity="TaskSet", inversedBy="tasks")
     */
    private $taskset;

generated SQL looks like:

CREATE TABLE task (
    id INT AUTO_INCREMENT NOT NULL, 
    taskset_id INT DEFAULT NULL, 
    INDEX IDX_527EDB255D67FAA4 (taskset_id), PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB;

CREATE TABLE task_set (
    id INT AUTO_INCREMENT NOT NULL, 
    PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB;   

ALTER TABLE task ADD CONSTRAINT FK_527EDB255D67FAA4 FOREIGN KEY (taskset_id) REFERENCES task_set (id)

Since now everything is well, I get one(testset) to many(test) bidirectional relation.

Unfortunately Doctrine2 chooses Task entity as owning side so this code is not persisting relation between entities:

$em = $this->getDoctrine()->getEntityManager();

$taskset = new TaskSet();
$taskset->setName('task 1');
$taskset->setDescription('desc 1');

$task =  new Task();
$task->setName('task 1');
$task->setClassName('class name 1');
$taskset->addTask($task);

$em->persist($taskset);
$em->flush();

output from code above is:

INSERT INTO `task_set` (`id`, `name`, `description`) VALUES (1, 'task 1', 'desc 1');
INSERT INTO `task` (`id`, `taskset_id`, `name`, `className`) VALUES (1, NULL, 'task 1', 'class name 1');

So finally questions:

  1. Is there a way to change owning side (of course I cannot revert relation)?
  2. How mark taskset_id as NOT NULL?

  1. In class TaskSet, edit the addTask($task) function and add at the end:

    $task->setTaskset($this);

  2. As Carlos said in comment, my initial post doesn't really answer the issue. You must use the nullable property on the JoinColumn definition:

    class Task { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id;

    /**
     * @var TaskSet $taskset
     * 
     * @ORM\JoinColumn(nullable=false)
     * @ORM\ManyToOne(targetEntity="TaskSet", inversedBy="tasks")
     */
    private $taskset;
    

Initial answer:

  1. Use a Validator, in your case the NotNull validator, on the $taskset property of your Task class.

Example from Symfony2's documentation:

// src/Acme/BlogBundle/Entity/Author.php
use Symfony\Component\Validator\Constraints as Assert;

class Author
{
    /**
     * @Assert\NotNull()
     */
    protected $firstName;
}

For 1

Add

$task->setTaskSet($taskset);

It will not change the owning side but the relation will be saved