6
votes

I've got the following classes (only show partials to reduce amount to read)

class Page {
    /**
     * @ORM\Column(type="string", unique=true, nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     * @var string
     */
    protected $id;
    /**
     * @ORM\OneToMany(targetEntity="Url", mappedBy="content")
     * @var Url[]
     */
    protected $urls;

    public function __construct()
    {
        $this->urls = new ArrayCollection();
    }
}

And:

class Url
{
    /**
     * @ORM\Id @ORM\Column(type="string", unique=true, nullable=false)
     * @ORM\GeneratedValue(strategy="UUID")
     * @var string The unique identifier for the Url
     */
    protected $id;
    /**
     * @ORM\ManyToOne(targetEntity="Page", inversedBy="urls", cascade={"persist", "merge"})
     * @ORM\JoinColumn(name="content_id", referencedColumnName="id")
     * @var int The UUID of the content
     */
    protected $content;

    public function __construct(Page $content, $link)
    {
        $this->content = $content;
        $this->content->addUrl($this);
    }
}

Each of these has a manager class with a save() function which just uses persist() and flush(). Saving them is then done as:

$pageManager->save($post);
$url = new Url($post, 'link goes here');
$urlManager->save($url);

I've also tried:

$url = new Url($post, 'link goes here');
$pageManager->save($post);
$urlManager->save($url);

Though in both instances I get:

( ! ) Fatal error: Uncaught exception 'Doctrine\ORM\ORMInvalidArgumentException' with message 'A managed+dirty entity Page@000000003d5a4ca10000000133ba3c3e can not be scheduled for insertion.'

I've tried this both with and without using AnnotationReader being used with EntityManager::create()

Doctrine's schema validator doesn't report any errors either:

php vendor/bin/doctrine orm:validate-schema
[Mapping]  OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.

Any ideas how to get the persist() to work?

2

2 Answers

0
votes

figured it out:

I had to reverse the order they were saved in, so the Url is saved first, and then Page (though in doing so it's opened up another issue I need to resolve where it wants to persist the author entity but can't (it thinks it's new, but it's not). Thought maybe it was detached, but even a merge() doesn't solve it.

/**
 * @ORM\ManyToOne(targetEntity="User")
 * @ORM\JoinColumn(name="author_id", referencedColumnName="id")
 * @var string The UUID of the author for the {@link Page}
 */
protected $author;
0
votes

You must persist the $post and the $url objects before flush(). Otherwise you're going to have this error message.

Try to do this...

$entityManager->persist($post);
$url = new Url($post, 'link goes here');
$entityManager->persist($url);
$entityManager->flush();

Or you can create a flag param on your managers, to not flush if false...

$flush = false;
$pageManager->save($post, $flush);
$url = new Url($post, 'link goes here');
$urlManager->save($url);

It will probably work without any additional resources.