darkbluesun
darkbluesun

Reputation: 827

Doctrine one-to-many relationship AND many-to-one

I have two tables. I want to set up a one-to-many relationship, but also a many-to-one relationship.

A Page can have one Background - this is the background of the page.

A Page can also have many Backgrounds - this is a collection of user-uploaded backgrounds from which one will be chosen for the first relationship.

In other words, a user selects a background from a bunch of predefined backgrounds, or one of many backgrounds he has uploaded to try out.

edit: When deleting a background, I want all pages with that background_id to have background_id set to null. When deleting a page, I want all the custom backgrounds belonging to that page to be deleted.

Whilst doctrine and symfony allow the above configuration, when deleting the page Doctrine ignores cascade="{remove}" on the Backgrounds property entirely, and of course an exception is raised when trying to delete the Page before deleting it's custom Backgrounds.

What am I doing wrong?

class Background
{
/**
 * @var string
 *
 * This attribute is for user uploaded backgrounds.
 *
 * @ORM\ManyToOne(targetEntity="Page",inversedBy="customBackgrounds")
 * @ORM\JoinColumn(name="page_id",referencedColumnName="id")
 */
protected $page;

/**
 * @var string
 *
 * This field helps admins to gauge popularity
 *
 * @ORM\OneToMany(targetEntity="Page",mappedBy="background")
 */
protected $pages;
}


class Page
{
/**
 * @var string
 *
 * @ORM\ManyToOne(targetEntity="Background",inversedBy="pages")
 * @ORM\JoinColumn(name="background_id",referencedColumnName="id", nullable=true, onDelete="SET NULL")
 */
protected $background;

/**
 * @ORM\OneToMany(targetEntity="Background", mappedBy="page", cascade={"remove"})
 * @ORM\OrderBy({"id" = "ASC"})
 */
protected $customBackgrounds;
}

Upvotes: 2

Views: 1033

Answers (3)

Greg
Greg

Reputation: 803

/**
 * @ORM\OneToMany(targetEntity="Background", mappedBy="page", orphanRemoval=true)
 * @ORM\OrderBy({"id" = "ASC"})
 */
protected $customBackgrounds;

Should do the trick (Doctrine - Orphan Removal)

Upvotes: 0

dariusphp
dariusphp

Reputation: 93

try @ORM\JoinColumn(name="page_id",referencedColumnName="id", onDelete="SET NULL") and do a schema update.

EDIT: The problem is at the database level not at doctrine's, the cascade="remove" takes care of that, the foreign key for page_id however, stays, the onDelete indicates that if a column with that foreign relationship is deleted, set the field to "value" this case its null. if you --dump-sql before schema update'ing you would see the query addition, something along the lines of " ON DELETE SET * "

More Info can be found Here: http://www.techonthenet.com/oracle/foreign_keys/foreign_null.php

Upvotes: 4

EsopMx
EsopMx

Reputation: 85

The only thing that maybe you can do, is use an event listener in your entity and when a page is deleted, set its background to null or another id

Upvotes: 0

Related Questions