Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Invalid
    • Affects Version/s: 2.3.4
    • Fix Version/s: None
    • Component/s: ORM
    • Labels:
      None
    • Environment:
      Osx

      Description

      If you have lazy association (example many-to-one) that have empty id (for empty i mean empty string and not null) you (correctly) get EntityNotFoundException.

      But i'm working with a system that sometimes put an empty string instead of null in fk fields.

      So i've add this little snipped of code __load method in $_proxyClassTemplate, ProxyFactory:

      // GT, 2013-05-21 If all identifier are empty you not need to try load
      
              if (is_array($this->_identifier)) {
                  $isEmpty = true;
                  foreach($this->_identifier as $iK => $iV) {
                      if (!empty($iV))
                          $isEmpty = false;
                  }
      
                  if ($isEmpty)
                      return;
              }
              // END GT EDIT
      

        Activity

        Hide
        Marco Pivetta added a comment -

        What does `$this->_identifier` contain in your failing case?

        Show
        Marco Pivetta added a comment - What does `$this->_identifier` contain in your failing case?
        Hide
        Gabriele Tondi added a comment - - edited

        It contains for example

        array(
        [id] =>
        );
        

        Because on db you find an empty string and not a null value.

        Show
        Gabriele Tondi added a comment - - edited It contains for example array( [id] => ); Because on db you find an empty string and not a null value.
        Hide
        Marco Pivetta added a comment - - edited

        If I get it correctly, you are using empty strings to emulate NULL references, which is invalid in SQL ( I've explained it extensively at http://stackoverflow.com/questions/15502408/doctrine-2-use-default-0-values-instead-of-null-for-relation/15511715#15511715 )

        Is this what you are doing? Because for any identifier that is not NULL an attempt to load it should be run, regardless of its content.

        Show
        Marco Pivetta added a comment - - edited If I get it correctly, you are using empty strings to emulate NULL references, which is invalid in SQL ( I've explained it extensively at http://stackoverflow.com/questions/15502408/doctrine-2-use-default-0-values-instead-of-null-for-relation/15511715#15511715 ) Is this what you are doing? Because for any identifier that is not NULL an attempt to load it should be run, regardless of its content.
        Hide
        Gabriele Tondi added a comment -

        That's not me

        It's the system by which i'm sharing the db.
        It uses MyIsam engine with no fk or index, so i've found this way to skip load when on db i've empty strings.

        Are there other (maybe cleaner) ways?

        Thanks,
        Gabriele

        Show
        Gabriele Tondi added a comment - That's not me It's the system by which i'm sharing the db. It uses MyIsam engine with no fk or index, so i've found this way to skip load when on db i've empty strings. Are there other (maybe cleaner) ways? Thanks, Gabriele
        Hide
        Marco Pivetta added a comment -

        No, the only correct way to handle this is to set NULL values for the association meta-columns. Marking as invalid

        Show
        Marco Pivetta added a comment - No, the only correct way to handle this is to set NULL values for the association meta-columns. Marking as invalid
        Show
        Gabriele Tondi added a comment - I can't find doc about it: https://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html?highlight=column#annref-column Can you give an example?
        Hide
        Marco Pivetta added a comment -

        `$this->someAssociation = NULL;`. That's basically what I mean.

        Show
        Marco Pivetta added a comment - `$this->someAssociation = NULL;`. That's basically what I mean.
        Hide
        Gabriele Tondi added a comment -

        Mmm, didn't understand.

        Anyway, we've tried to fix the old Delphi Monster witch store empty strings instead of nulls... with no results.

        So, here is my workaround, maybe this can be useful for other developers who will be in troubles in the future..

        In "UnitOfWork" class, public method "createEntity".

        [...]

        UnitOfWork.php
         
        // TODO: Is this even computed right in all cases of composite keys?
                            foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
                                $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
        
                                // START-EDIT
        
                                // GT: our moas store empty string instead of null in fk columns.
                                // So, let's check and handle it as null!
        
                                if (empty($joinColumnValue))
                                    $joinColumnValue = null;
        
                                // END-EDIT
        
                                if ($joinColumnValue !== null) {
                                    if ($targetClass->containsForeignIdentifier) {
                                        $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue;
                                    } else {
                                        $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
                                    }
                                }
                            }
        

        [...]

        Regards,
        Gabriele

        Show
        Gabriele Tondi added a comment - Mmm, didn't understand. Anyway, we've tried to fix the old Delphi Monster witch store empty strings instead of nulls... with no results. So, here is my workaround, maybe this can be useful for other developers who will be in troubles in the future.. In "UnitOfWork" class, public method "createEntity". [...] UnitOfWork.php // TODO: Is this even computed right in all cases of composite keys? foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) { $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null ; // START-EDIT // GT: our moas store empty string instead of null in fk columns. // So, let's check and handle it as null ! if (empty($joinColumnValue)) $joinColumnValue = null ; // END-EDIT if ($joinColumnValue !== null ) { if ($targetClass->containsForeignIdentifier) { $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue; } else { $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue; } } } [...] Regards, Gabriele
        Hide
        Marco Pivetta added a comment -

        Gabriele Tondi the ORM does not deal with such architectures (nor with generally invalid usage of RDBMS systems). The only acceptable solution in ORM is with correct NULL values, as it should be, so this patch is invalid.

        Show
        Marco Pivetta added a comment - Gabriele Tondi the ORM does not deal with such architectures (nor with generally invalid usage of RDBMS systems). The only acceptable solution in ORM is with correct NULL values, as it should be, so this patch is invalid.

          People

          • Assignee:
            Marco Pivetta
            Reporter:
            Gabriele Tondi
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: