Canser Yanbakan
Canser Yanbakan

Reputation: 3870

A bit confused about database relations - Doctrine2 YAML

I'm a bit confused about relations between entities like manyToMany, oneToMany etc.

What i'm confused about exactly is, if i remove or delete a record from database, how can we say delete relational entities either.

For example:

manyToMany

Category Entity:

manyToMany:
    posts:
      targetEntity: PostEntity
      mappedBy: taxonomies

Scenario one:

If you remove or delete one of these categories, immediately delete all relations in post_taxonomy_relations table. What can we use to do this? Cascade or Orphanremoval?

Post Entity:

manyToMany:
    taxonomies:
      targetEntity: TaxonomyEntity
      inversedBy: posts
      joinTable:
        name: post_taxonomy_relations
        joinColumns:
          post_id:
            referencedColumnName: id
        inverseJoinColumns:
          taxonomy_id:
            referencedColumnName: id

Scenario two:

If you only delete (db level) one of these records, delete related entity in post_taxonomy_relations

oneToMany & manyToOne

Post Template Entity:

  oneToMany:
    products:
      targetEntity: PostEntity
      cascade: ["remove"]
      mappedBy: post_template
      joinColumn:
        name: id
        referencedColumnName: template_id

Scenario one:

If you remove one of these entities, remove related posts either. Works with cascade: ["remove"]. But if you delete this entity (db level) set null or delete related posts too. How can we do this?

Post Entity:

  manyToOne:
    template:
      targetEntity: PostTemplateEntity
      inversedBy: products
      joinColumn:
        name: template_id
        referencedColumnName: id

If you remove or delete this post, do nothing.

Okay, i'm trying to get used to these cascade operations.

Every answer that has samples in it, are most valuable for me. Thank you.

Upvotes: 1

Views: 58

Answers (1)

Cascade operations are performed in memory. That means collections and related entities are fetched into memory, even if they are still marked as lazy when the cascade operation is about to be performed.

To rely on the database level cascade operations for the delete operation instead, you can configure each join column with the onDelete option by setting it CASCADE.

When using the orphanRemoval=true option Doctrine makes the assumption that the entities are privately owned and will NOT be reused by other entities. If you neglect this assumption your entities will get deleted by Doctrine even if you assigned the orphaned entity to another one.

Based on your template, you can try:

oneToMany:
  products:
    targetEntity: PostEntity
    mappedBy: post_template
    joinColumn:
      name: id
      referencedColumnName: template_id
      onDelete: CASCADE


manyToOne:
  template:
    targetEntity: PostTemplateEntity
    inversedBy: products
    cascade: ["remove"]
    joinColumn:
      name: template_id
      referencedColumnName: id

In many-to-many relations I have no idea based on yaml configuration. Only I know is manually, such as:

foreach ($user->getRoles() as $role) {
    $user->removeRole($role)
}
$em->remove($user);
$em->flush();

Upvotes: 2

Related Questions