13

I have two entities

class Promotor
{

/**
 * @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor")
 * @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false)
 */
protected $ciudad;

and

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

/**
 * @var string
 *
 * @ORM\Column(name="nombre", type="string", length=50)
 */
private $nombre;

A "Promotor" can live in one "Ciudad" (City). And in a "Ciudad" (City) can live many "Promotores".

If i add onDelete="CASCADE" in JoinColumn

/**
 * @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor")
 * @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 */
protected $ciudad;

it generate the next code

ALTER TABLE promotor DROP FOREIGN KEY FK_BF20A37FE8608214;
ALTER TABLE promotor ADD CONSTRAINT FK_BF20A37FE8608214 FOREIGN KEY (ciudad_id)
REFERENCES Ciudad (id) ON DELETE CASCADE

but also i like do CASCADE on update. I try with onUpdate="CASCADE" but it doesn' work

[Doctrine\Common\Annotations\AnnotationException]
[Creation Error] The annotation @ORM\JoinColumn declared on property     Web\PromotorBundle\Entity\Promotor::$ciudad does not have a property named
"onUpdate". Available properties: name, referencedColumnName, unique, nulla
ble, onDelete, columnDefinition, fieldName

By the error I understand that the property onUpdate does not exist, but.. Is there any way to do cascade on update?

JGrinon
  • 1,453
  • 1
  • 14
  • 36
  • 1
    I found this note in the documentation of doctrine, but I do not understand. It is no longer necessary to control the cascade on update. In theory it will never change the ids http://www.doctrine-project.org/jira/browse/DDC-725?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel – JGrinon Apr 25 '13 at 05:33

1 Answers1

16

The onDelete="CASCADE" is used on the database level. As you already said there is no onUpdate. Another downside is that ON DELETE CASCADE only works on InnoDB. It doesn't work on MyISAM.

But you can use Doctrine in-memory cascade operations:

class Promotor
{

/**
* @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false)
*/
protected $ciudad;

It's all described in the documentation: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

Plus you can skip the JoinColumn annotation, because the way you have it written, is the default configuration and it's generated implicitly.

So you can just write:

class Promotor
{

/**
* @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor", cascade={"persist", "remove"})
*/
protected $ciudad;
localheinz
  • 9,179
  • 2
  • 33
  • 44
alsar
  • 186
  • 1
  • 5
  • BTW, how come there is `inversedBy="promotor"` on the `$ciudad` property, if the `Ciudad` entity does NOT have field `$promotor` ? (And even from the nature of MTO relationships, it CAN NOT have 'inverse' reference to `Promotor` at all)? – Dimitry K May 20 '14 at 18:19
  • You are right, there is no `promotor` property on the `Ciudad` entity. So there can't be `inversedBy="promotor"`. But you're wrong about the ManyToOne relationship and the `inverse` reference. ManyToOne has `inverse` and OneToMany has `mappedBy`. – alsar May 21 '14 at 06:28
  • Sorry, my wording was not precise enough. When I said 'inverse' I actually meant same `inversedBy`. Also though it seems logical what you have said (that there can't be `inversedBy="promotor"`) I looked up the docs for `@ManyToOne` http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-manytoone and it mentiones this `inversedBy` parameter (though not as obligatory). But I am still confused as of - how come an MTO relationship may have `inversedBy`? Isn't it true that, may there have been `inversedBy` that would be ManyToMany relationship? – Dimitry K May 21 '14 at 10:32
  • 2
    I think I figured it out: As per documentation `The inversedBy attribute designates the field in the entity that is the inverse side of the relationship.` The key word is `field in the entity` - it is a field in other entity (but in the other entity representation in the database there will be NO extra fields added for that relationship). And it is still MTO to OTM relationship. – Dimitry K May 23 '14 at 15:14