DDC-3125: Better Exception Descriptions / Undefined index Handling #3865

Closed
opened 2026-01-22 14:29:19 +01:00 by admin · 13 comments
Owner

Originally created by @doctrinebot on GitHub (May 2, 2014).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user patzerr:

Some warnings are not very helpful for beginners if the presented text does not state what the Code is trying to accomplish.

Example:
{quote}Notice: Undefined index: test in /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1753{quote}

And followed by another warning:
{quote}Warning: Invalid argument supplied for foreach() in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1758{quote}

Another example:
{quote}Notice: Undefined index: unknownField in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2611{quote}

-> Resulted from a wrong defition: {quote}@ORM\JoinColumn(referencedColumnName="unknownField"){quote}

Possible Fix:

private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
    {
        $criteria = array();
        if ( ! isset($this->class->associationMappings[$assoc['mappedBy']])) {
          throw new MappingException(
            "No associations/mappings defined for " . $assoc['mappedBy'].
            ". Available: " . implode(', ', array_keys($this->class->associationMappings))
          );
        }
...
Originally created by @doctrinebot on GitHub (May 2, 2014). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user patzerr: Some warnings are not very helpful for beginners if the presented text does not state what the Code is trying to accomplish. Example: {quote}Notice: Undefined index: test in /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1753{quote} And followed by another warning: {quote}Warning: Invalid argument supplied for foreach() in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1758{quote} Another example: {quote}Notice: Undefined index: unknownField in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2611{quote} -> Resulted from a wrong defition: {quote}@ORM\JoinColumn(referencedColumnName="unknownField"){quote} Possible Fix: ``` private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null) { $criteria = array(); if ( ! isset($this->class->associationMappings[$assoc['mappedBy']])) { throw new MappingException( "No associations/mappings defined for " . $assoc['mappedBy']. ". Available: " . implode(', ', array_keys($this->class->associationMappings)) ); } ... ```
admin added the Improvement label 2026-01-22 14:29:19 +01:00
admin closed this issue 2026-01-22 14:29:19 +01:00
Author
Owner

@doctrinebot commented on GitHub (May 2, 2014):

Comment created by patzerr:

Possible fix for the warning in the UnitOfWork-Class (Line 2610)

if ($joinColumnValue !== null) {
  if ($targetClass->containsForeignIdentifier) {
    $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue;
  } else {
<ins>  if ( ! isset($targetClass->fieldNames[$targetColumn])) {
</ins>    throw new Exception("Entity ".$targetClass->getName(). ' has no field named '.$targetColumn);
+  }
   $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
  }
}
@doctrinebot commented on GitHub (May 2, 2014): Comment created by patzerr: Possible fix for the warning in the UnitOfWork-Class (Line 2610) ``` if ($joinColumnValue !== null) { if ($targetClass->containsForeignIdentifier) { $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue; } else { <ins> if ( ! isset($targetClass->fieldNames[$targetColumn])) { </ins> throw new Exception("Entity ".$targetClass->getName(). ' has no field named '.$targetColumn); + } $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue; } } ```
Author
Owner

@doctrinebot commented on GitHub (May 2, 2014):

Comment created by @ocramius:

Did you validate your metadata mappings first?

@doctrinebot commented on GitHub (May 2, 2014): Comment created by @ocramius: Did you validate your metadata mappings first?
Author
Owner

@doctrinebot commented on GitHub (May 5, 2014):

Comment created by patzerr:

{quote}
php vendor/bin/doctrine orm:validate-schema
[Mapping] FAIL - The entity-class 'Game' mapping is invalid:

  • The referenced column name 'unknownColumn' has to be a primary key column on the target entity class 'Publisher'.
    {quote}

Ah, found my problem: I was using a different bootstrapping (since i tried XML first then switched over to Annotations) for the cli-configuration (config/cli.php) and the XML-Mappings were still valid.

Maybe the exception-message could simply contain a note stating "please run the schema validator [link to documentation]" to help beginners.

Thank you very much for your time.

@doctrinebot commented on GitHub (May 5, 2014): Comment created by patzerr: {quote} php vendor/bin/doctrine orm:validate-schema [Mapping] FAIL - The entity-class 'Game' mapping is invalid: - The referenced column name 'unknownColumn' has to be a primary key column on the target entity class 'Publisher'. {quote} Ah, found my problem: I was using a different bootstrapping (since i tried XML first then switched over to Annotations) for the cli-configuration (config/cli.php) and the XML-Mappings were still valid. Maybe the exception-message could simply contain a note stating "please run the schema validator [link to documentation]" to help beginners. Thank you very much for your time.
Author
Owner

@doctrinebot commented on GitHub (May 14, 2014):

Comment created by patzerr:

Found more:

I removed an already existing Entity and then readded it. Calling EntityManager->flush resulted in the following warnings:

{quote}
Notice: Undefined index: 000000002881c5e0000000006153a26a in /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2860

Call Stack:
0.0003 691360 1. main() /test.php:0
0.6119 11843448 2. Doctrine\ORM\EntityManager->flush() /test.php:68
0.6119 11843528 3. Doctrine\ORM\UnitOfWork->commit() /vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:389
0.6499 12226904 4. Doctrine\ORM\Persisters\AbstractCollectionPersister->update() /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:356
0.6499 12226904 5. Doctrine\ORM\Persisters\AbstractCollectionPersister->deleteRows() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:131
0.6501 12227544 6. Doctrine\ORM\Persisters\ManyToManyPersister->getDeleteRowSQLParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:148
0.6501 12227544 7. Doctrine\ORM\Persisters\ManyToManyPersister->collectJoinTableColumnParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:69
0.6502 12227936 8. Doctrine\ORM\UnitOfWork->getEntityIdentifier() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:136

Warning: array_pop() expects parameter 1 to be array, null given in /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php on line 147

Call Stack:
0.0003 691360 1. main() /test.php:0
0.6119 11843448 2. Doctrine\ORM\EntityManager->flush() /test.php:68
0.6119 11843528 3. Doctrine\ORM\UnitOfWork->commit() /vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:389
0.6499 12226904 4. Doctrine\ORM\Persisters\AbstractCollectionPersister->update() /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:356
0.6499 12226904 5. Doctrine\ORM\Persisters\AbstractCollectionPersister->deleteRows() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:131
0.6501 12227544 6. Doctrine\ORM\Persisters\ManyToManyPersister->getDeleteRowSQLParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:148
0.6501 12227544 7. Doctrine\ORM\Persisters\ManyToManyPersister->collectJoinTableColumnParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:69
0.6504 12228744 8. array_pop() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:147
{quote}

try {
  $deleteMe= $entityManager->find('de\gamepay\db\Game', 'test_game');
  if ($deleteMe) {
    $entityManager->remove($deleteMe);
    $entityManager->flush();
  }
} catch (Exception $ex) {}

$newGame= new de\gamepay\db\Game();
$newGame->setGameId('test_game');
$newGame->setPublisher($existingPublisher);
$entityManager->persist($newGame);
// The following line results in the warnings. 
$entityManager->flush();
// Still works and surpresses the warnings: @$entityManager->flush();

The game gets added, but i don't know why there are warnings.

@doctrinebot commented on GitHub (May 14, 2014): Comment created by patzerr: Found more: I removed an already existing Entity and then readded it. Calling EntityManager->flush resulted in the following warnings: {quote} Notice: Undefined index: 000000002881c5e0000000006153a26a in /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2860 Call Stack: 0.0003 691360 1. main() /test.php:0 0.6119 11843448 2. Doctrine\ORM\EntityManager->flush() /test.php:68 0.6119 11843528 3. Doctrine\ORM\UnitOfWork->commit() /vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:389 0.6499 12226904 4. Doctrine\ORM\Persisters\AbstractCollectionPersister->update() /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:356 0.6499 12226904 5. Doctrine\ORM\Persisters\AbstractCollectionPersister->deleteRows() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:131 0.6501 12227544 6. Doctrine\ORM\Persisters\ManyToManyPersister->getDeleteRowSQLParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:148 0.6501 12227544 7. Doctrine\ORM\Persisters\ManyToManyPersister->collectJoinTableColumnParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:69 0.6502 12227936 8. Doctrine\ORM\UnitOfWork->getEntityIdentifier() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:136 Warning: array_pop() expects parameter 1 to be array, null given in /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php on line 147 Call Stack: 0.0003 691360 1. main() /test.php:0 0.6119 11843448 2. Doctrine\ORM\EntityManager->flush() /test.php:68 0.6119 11843528 3. Doctrine\ORM\UnitOfWork->commit() /vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:389 0.6499 12226904 4. Doctrine\ORM\Persisters\AbstractCollectionPersister->update() /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:356 0.6499 12226904 5. Doctrine\ORM\Persisters\AbstractCollectionPersister->deleteRows() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:131 0.6501 12227544 6. Doctrine\ORM\Persisters\ManyToManyPersister->getDeleteRowSQLParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php:148 0.6501 12227544 7. Doctrine\ORM\Persisters\ManyToManyPersister->collectJoinTableColumnParameters() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:69 0.6504 12228744 8. array_pop() /vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:147 {quote} ``` try { $deleteMe= $entityManager->find('de\gamepay\db\Game', 'test_game'); if ($deleteMe) { $entityManager->remove($deleteMe); $entityManager->flush(); } } catch (Exception $ex) {} $newGame= new de\gamepay\db\Game(); $newGame->setGameId('test_game'); $newGame->setPublisher($existingPublisher); $entityManager->persist($newGame); // The following line results in the warnings. $entityManager->flush(); // Still works and surpresses the warnings: @$entityManager->flush(); ``` The game gets added, but i don't know why there are warnings.
Author
Owner

@doctrinebot commented on GitHub (May 14, 2014):

Comment created by @ocramius:

These are all validation-related errors.

Doctrine can't register a php error listener (for notices/warnings), as that would affect the global environment, so this cannot be fixed without introducing checks in all the locations where valid metadata was expected.

@doctrinebot commented on GitHub (May 14, 2014): Comment created by @ocramius: These are all validation-related errors. Doctrine can't register a php error listener (for notices/warnings), as that would affect the global environment, so this cannot be fixed without introducing checks in all the locations where valid metadata was expected.
Author
Owner

@doctrinebot commented on GitHub (May 14, 2014):

Issue was closed with resolution "Can't Fix"

@doctrinebot commented on GitHub (May 14, 2014): Issue was closed with resolution "Can't Fix"
Author
Owner

@doctrinebot commented on GitHub (May 15, 2014):

Comment created by patzerr:

For the sake of completeness:
orm:validate-schema
[Mapping] OK - The mapping files are correct.

Furthermore the index in the message "Notice: Undefined index: 000000002881c5e0000000006153a26a in /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2860" is changing on every run.

All this ticket was about to either suppress these warnings the user can't fix or do checks to prevent the warnings when accessing not existing indexes.
IMHO code that throws warnings at the user he can't really work around is not optimal, particular for beginners like me.

@doctrinebot commented on GitHub (May 15, 2014): Comment created by patzerr: For the sake of completeness: orm:validate-schema [Mapping] OK - The mapping files are correct. Furthermore the index in the message "Notice: Undefined index: 000000002881c5e0000000006153a26a in /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2860" is changing on every run. All this ticket was about to either suppress these warnings the user can't fix or do checks to prevent the warnings when accessing not existing indexes. IMHO code that throws warnings at the user he can't really work around is not optimal, particular for beginners like me.
Author
Owner

@doctrinebot commented on GitHub (May 15, 2014):

Comment created by @ocramius:

Yes, but we can't build checks into the persisters/hydrators because of performance issues.

As of your failure, the operation you are executing in your example is invalid, as you are trying to register another entity (same identifier) in the same UoW.

@doctrinebot commented on GitHub (May 15, 2014): Comment created by @ocramius: Yes, but we can't build checks into the persisters/hydrators because of performance issues. As of your failure, the operation you are executing in your example is invalid, as you are trying to register another entity (same identifier) in the same UoW.
Author
Owner

@doctrinebot commented on GitHub (May 16, 2014):

Comment created by @deeky666:

TBH I'm with [~ocramius] opinion. UoW is a very performance sensitive component and we should not try to catch every edge case just because of invalid usage. Maybe we just need to improve the documentation on this (for your use cases).

@doctrinebot commented on GitHub (May 16, 2014): Comment created by @deeky666: TBH I'm with [~ocramius] opinion. UoW is a very performance sensitive component and we should not try to catch every edge case just because of invalid usage. Maybe we just need to improve the documentation on this (for your use cases).
Author
Owner

@doctrinebot commented on GitHub (May 16, 2014):

Comment created by @ocramius:

Not sure where it is documented (can't find it atm), but I thought it is clear that the UoW works under the assumption that there is only one object per identifier per type in the UoW at any time.

@doctrinebot commented on GitHub (May 16, 2014): Comment created by @ocramius: Not sure where it is documented (can't find it atm), but I thought it is clear that the UoW works under the assumption that there is only one object per identifier per type in the UoW at any time.
Author
Owner

@doctrinebot commented on GitHub (Jun 5, 2014):

Comment created by patzerr:

Found another one when writing Repository-Classes:

{quote}
PHP Notice: Undefined index: publisher in [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php on line 415
PHP Stack trace:
{...]
PHP 4. Doctrine\ORM\AbstractQuery->execute() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:574
PHP 5. Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:804
PHP 6. Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateAllData() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:140
PHP 7. Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateRowData() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:179
{quote}

Schema validation says (since the problem is in the Repository-class):
{quote}
[Mapping] OK - The mapping files are correct.
{quote}

I have a many-to-one and a one-to-many relation like in this example:
http://codemonkeys.be/2013/02/example-of-a-doctrine-2-x-many-to-many-association-class/

Thx in advance

@doctrinebot commented on GitHub (Jun 5, 2014): Comment created by patzerr: Found another one when writing Repository-Classes: {quote} PHP Notice: Undefined index: publisher in [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php on line 415 PHP Stack trace: {...] PHP 4. Doctrine\ORM\AbstractQuery->execute() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:574 PHP 5. Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:804 PHP 6. Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateAllData() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:140 PHP 7. Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateRowData() [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:179 {quote} Schema validation says (since the problem is in the Repository-class): {quote} [Mapping] OK - The mapping files are correct. {quote} I have a many-to-one and a one-to-many relation like in this example: http://codemonkeys.be/2013/02/example-of-a-doctrine-2-x-many-to-many-association-class/ Thx in advance
Author
Owner

@doctrinebot commented on GitHub (Jun 6, 2014):

Comment created by @ocramius:

[~patzerr] there is no publisher field in the linked example

@doctrinebot commented on GitHub (Jun 6, 2014): Comment created by @ocramius: [~patzerr] there is no `publisher` field in the linked example
Author
Owner

@doctrinebot commented on GitHub (Jun 6, 2014):

Comment created by patzerr:

Here is an example:
http://pastebin.com/SN1s2xU8

Testdata is in the class-comment, see the Repository-Class on how to provoke the warning ("Undefined index: id in DoctrineTest/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2487").

Just to make my point clear and point out why the warning is puzzling for beginners:
I asked myself "why is there an index 'id' missing?" - after debugging around in the code to see what's what i remembered Doctrine is using "id" as the identifier as default if no other name is given (in this example: "p_publisher_id" was missing in the resultset) and it seems to miss a value.

The warning should have contained why it was trying to access that "id"-field (e.g. "tried to get value p_publisher_id or id - neither was found - check your resultset").

hth
Kind regards

@doctrinebot commented on GitHub (Jun 6, 2014): Comment created by patzerr: Here is an example: http://pastebin.com/SN1s2xU8 Testdata is in the class-comment, see the Repository-Class on how to provoke the warning ("Undefined index: id in DoctrineTest/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2487"). Just to make my point clear and point out why the warning is puzzling for beginners: I asked myself "why is there an index 'id' missing?" - after debugging around in the code to see what's what i remembered Doctrine is using "id" as the identifier as default if no other name is given (in this example: "p_publisher_id" was missing in the resultset) and it seems to miss a value. The warning should have contained why it was trying to access that "id"-field (e.g. "tried to get value p_publisher_id or id - neither was found - check your resultset"). hth Kind regards
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#3865