Doctrine merge: Notice: Undefined index: id

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • gnoe93
  • Registratie: September 2016
  • Laatst online: 08-04 13:00
Ij heb een hoop geneste entities die ik wil mergen met de entity manager, maar ik krijg een "ContextErrorException" als een bepaalde property (entity collection) één of meer items bevat:

code:
1
2
3
4
5
Symfony\Component\Debug\Exception\ContextErrorException:

Notice: Undefined index: id at vendor/doctrine/orm/lib/Doctrine/ORM/Utility/IdentifierFlattener.php:97
at Doctrine\ORM\Utility\IdentifierFlattener-> flattenIdentifier(object(ClassMetadata), array()) (vendor/doctrine/orm/lib/Doctrine/ORM/Utility/IdentifierFlattener.php:84)
at Doctrine\ORM\Utility\IdentifierFlattener-> flattenIdentifier(object(ClassMetadata), array('attack' => object(CardAttack), 'type' => object(EnergyType))) (vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1838)


Hier is een dump van het object dat ik probeer te mergen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Card {#1124 ▼
  -id: null
  -attacks: ArrayCollection {#1225 ▼
    -elements: array:1 [▼
      0 => CardAttack {#1227 ▼
        -id: null
        -card: Card {#1124}
        -name: "22323"
        -energies: ArrayCollection {#1540 ▼
          -elements: array:2 [▼
            0 => CardAttackEnergy {#1217 ▼
              -attack: CardAttack {#1227}
              -type: EnergyType {#1536 ▼
                -id: 1
                -name: "Colorless"
                -symbolFilePath: "content/energy-type-symbols/colorless.png"
              }
              -amount: 1
            }
            1 => CardAttackEnergy {#1538 ▼
              -attack: CardAttack {#1227}
              -type: EnergyType {#1539 ▼
                -id: 3
                -name: "Dragon"
                -symbolFilePath: "content/energy-type-symbols/dragon.png"
              }
              -amount: 1
            }
          ]
        }
        -damage: "2"
        -description: null
      }
    ]
  }
}


Dit is de ORM mapping voor de entities:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CardRepository")
 * @ORM\Table(name="card")
 */
class Card
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @AccessType("public_method")
     * 
     * @Assert\Valid()
     * 
     * @ORM\OneToMany(
     *     targetEntity="\AppBundle\Entity\CardAttack",
     *     mappedBy="card",
     *     cascade="all",
     *     orphanRemoval=true
     * )
     * @ORM\OrderBy({"id"="ASC"})
     */
    private $attacks;
}

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

    /**
     * @Assert\NotBlank()
     * @Assert\Type("\AppBundle\Entity\Card")
     * @Assert\Valid()
     * 
     * @ORM\ManyToOne(targetEntity="\AppBundle\Entity\Card", inversedBy="attacks")
     * @ORM\JoinColumn(name="card_id", referencedColumnName="id")
     */
    private $card;

    /**
     * @Assert\NotBlank()
     * @Assert\Type(type="string")
     * @Assert\Length(max=50)
     * 
     * @ORM\Column(name="name", type="string", length=50)
     */
    private $name;

    /**
     * @AccessType("public_method")
     * 
     * @Assert\Valid()
     * @CustomAssert\UniqueCollectionEntity(field="type")
     * 
     * @ORM\OneToMany(
     *     targetEntity="\AppBundle\Entity\CardAttackEnergy", 
     *     mappedBy="attack",
     *     cascade="all",
     *     orphanRemoval=true
     * )
     */
    private $energies;

    /**
     * @Assert\Type(type="string")
     * @Assert\Length(max=5)
     *
     * @ORM\Column(name="damage", type="string", length=5)
     */
    private $damage;

    /**
     * @Assert\Type(type="string")
     * 
     * @ORM\Column(name="description", type="text")
     */
    private $description;
}

/**
 * @ORM\Entity
 * @ORM\Table(name="card_attack_has_energy")
 */
class CardAttackEnergy
{
    /**
     * @Assert\NotBlank()
     * @Assert\Type("\AppBundle\Entity\CardAttack")
     * @Assert\Valid()
     * 
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\AppBundle\Entity\CardAttack", inversedBy="energies")
     * @ORM\JoinColumn(name="card_attack_id", referencedColumnName="id")
     */
    private $attack;

    /**
     * @Assert\NotBlank()
     * @Assert\Type("\AppBundle\Entity\EnergyType")
     * @Assert\Valid()
     * 
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\AppBundle\Entity\EnergyType", cascade="merge")
     * @ORM\JoinColumn(name="energy_type_id", referencedColumnName="id")
     */
    private $type;

    /**
     * @Assert\NotBlank()
     * @Assert\Type(type="integer")
     * @Assert\Range(min=1, max=10)
     * 
     * @ORM\Column(name="amount", type="integer")
     */
    private $amount;
}


Ik heb alle andere properties van "Card" weggelaten aangezien het probleem enkel lijkt voor te komen bij de "energies" property van "cardAttack" (zoals te zien in de stack trace; "CardAttackEnergy" heeft een composite key bestaande uit "CardAttack" en "EnergyType").

Het probleem lijkt ook enkel voor te komen indien "CardAttackEnergy" verwijst naar een een nog niet bestaande "CardAttack". Is dit waar de "undefined index: id" vandaan komt (aangezien cardAttack->id === null)? Zouden de cascade merge opties niet eerst "CardAttack" moeten persisten en pas vervolgens "CardAttackEnergy" indien deze niet bestaan?

Beste antwoord (via gnoe93 op 28-08-2017 19:43)


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Ah, op die fiets.

Lijkt me niet, het lijkt erop dat Doctrine zelf ergens een id wil aanspreken op een array die geen id heeft. En dat lijkt te kloppen, CardAttackEnergy hééft geen veld genaamd id maar eentje genaamd attack. Die foreign key ook je primary key maken lijkt me niet heel handig, voeg eens een apart ID-veld toe? Zou zomaar eens kunnen dat Doctrine hier geen chocola van kan maken.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Alle reacties


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

gnoe93 schreef op maandag 28 augustus 2017 @ 17:06:
Is dit waar de "undefined index: id" vandaan komt (cardAttack.id === null)?
Waar komt dit vandaan? Lijkt op Twig en dus niet relevant?
Zouden de cascade merge opties niet eerst "CardAttack" moeten persisten en pas vervolgens "CardAttackEnergy" indien deze niet bestaan?
Klopt.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • gnoe93
  • Registratie: September 2016
  • Laatst online: 08-04 13:00
NMe schreef op maandag 28 augustus 2017 @ 17:17:
[...]

Waar komt dit vandaan? Lijkt op Twig en dus niet relevant?
Hiermee wil ik gewoon zeggen dat de "id" van het "cardAttack" object "null" is, was gewoon vergeten de PHP notatie te gebruiken ;)

[ Voor 9% gewijzigd door gnoe93 op 28-08-2017 17:23 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

gnoe93 schreef op maandag 28 augustus 2017 @ 17:22:
[...]

Hiermee wil ik gewoon zeggen dat de "id" van het "cardAttack" object "null" is.
Dat snap ik, maar dit is geen PHP-code. Het ziet eruit als Twig, afgezien van het feit dat je === schrijft in plaats van is. Waar staat die check en wanneer voer je die uit?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • gnoe93
  • Registratie: September 2016
  • Laatst online: 08-04 13:00
NMe schreef op maandag 28 augustus 2017 @ 17:23:
[...]

Dat snap ik, maar dit is geen PHP-code. Het ziet eruit als Twig, afgezien van het feit dat je === schrijft in plaats van is. Waar staat die check en wanneer voer je die uit?
Die code staat nergens, ik wil gewoon zeggen dat de id op "null" staat (zie dump).

Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Ah, op die fiets.

Lijkt me niet, het lijkt erop dat Doctrine zelf ergens een id wil aanspreken op een array die geen id heeft. En dat lijkt te kloppen, CardAttackEnergy hééft geen veld genaamd id maar eentje genaamd attack. Die foreign key ook je primary key maken lijkt me niet heel handig, voeg eens een apart ID-veld toe? Zou zomaar eens kunnen dat Doctrine hier geen chocola van kan maken.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • gnoe93
  • Registratie: September 2016
  • Laatst online: 08-04 13:00
NMe schreef op maandag 28 augustus 2017 @ 17:27:
Ah, op die fiets.

Lijkt me niet, het lijkt erop dat Doctrine zelf ergens een id wil aanspreken op een array die geen id heeft. En dat lijkt te kloppen, CardAttackEnergy hééft geen veld genaamd id maar eentje genaamd attack. Die foreign key ook je primary key maken lijkt me niet heel handig, voeg eens een apart ID-veld toe? Zou zomaar eens kunnen dat Doctrine hier geen chocola van kan maken.
Ik heb even mijn database en entities aangepast, en dit heeft het probleem inderdaad verholpen. Dit is raar aangezien ik in het verleden met Doctrine reeds composite keys heb gebruikt in een gelijkaardig scenario. Misschien is dit (intentioneel?) veranderd?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Composite keys in Doctrine geven mij vrijwel altijd hoofdpijn dus ik voorkom het door altijd een eigen autoincrement-key toe te voegen. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • gnoe93
  • Registratie: September 2016
  • Laatst online: 08-04 13:00
NMe schreef op maandag 28 augustus 2017 @ 20:55:
Composite keys in Doctrine geven mij vrijwel altijd hoofdpijn dus ik voorkom het door altijd een eigen autoincrement-key toe te voegen. :)
Mijn toekomstige projecten die gebruik maken van een ORM zullen vanaf nu ook enkel surrogate keys bevatten ;)
Pagina: 1