Doctrine 1.2, i18n : Column not found: 1054 Unknown column ‘h.translated_field’ in ‘field list’

30 mai 2012 par: Benoit Bonneville

Dans Doctrine 1.2, généralement sous le framework symfony 1.4.
Vous utilisez i18n et vous avez l’erreur suivante :
SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘h.translated_field’ in ‘field list’

 

Doctrine:  Unknown column in ‘field list’ pour I18N Behaviors 

 

Mise en situation :

Vous utilisez Doctrine 1.2 l’ORM PHP.
Votre Schema Doctrine contiens un  » actAs: i18n « , c’est à dire un « Behaviors » d’internationalisation.
(i18n veux dire InternationalisatioN).

schema.yml :

 MyItem:
   actAs:
     I18n:
       fields: [translated_field]

Puis vérifiez que dans votre fichier BaseMyItem.class.php vous avez bien :

$i18n0 = new Doctrine_Template_I18n(array(
    'fields' =>
    array(
    0 => 'translated_field'
    ),
    ));
$this->actAs($i18n0);

(Ce code est mal indenté, c’est un copier coller du code généré par doctrine)
Rappel du path : ./lib/model/doctrine/base/BaseMyItem.class.php
Si vous ne l’avez pas, c’est que vous n’avez pas construit votre model (php symfony build-model)

Erreur la plus fréquente : votre model est erroné.

Votre base de donnée n’a pas la table Translation dont vous avez besoin avec le champ translated_field.
Je vous laisse regarder dans la documentations Doctrine. Nous allons traitez ici d’un bug particulier.

Erreur qui n’impact que l’i18n dans certains cas :

En temps normal cette erreur n’apparaît pas et vous parvenez à instancier un objet.
Le problème est une question de majuscule dans le nom de la table principale de votre requête.

Voici un exemple de code qui ne fonctionnera pas :

Doctrine::getTable('myItem')->find(1);
// any code execution and any scope change (class,function,method) ...
Doctrine::getTable('MyItem')->find(1);

Bien entendu ces 2 lignes peuvent être placées n’importe ou dans votre code. C’est à dire pas exclusivement dans la même méthode,fonction ou classe.
Cela impact aussi le champ ->from() de n’importe quelle Doctrine_Query.

Correction :

Recherchez tout vos appels au méthodes statique getTable() et tout vos méthode ->from() de votre projet et corrigez la casse.

Explication :

Si cela interesse quelqu’un,  Doctrine conserve en interne la déclaration du mapping de chacun des objet. Ils sont stoqués dans un tableau associatif, avec comme clef d’index , le nom de la classe, qui est insensible à la casse.

Dans ce tableau associatif vous retrouvez aussi les objet de traductions.  Mais ceux ci, dépendant du nom de l’objet de base, sont sensible à la casse !

Ce tableau se trouve dans le singleton Doctrine_Manager, paramètre protected « _bound« .
Le singleton explique que peu importe ou vous exécutiez votre code, le problème est présent, tant qu’il s’agit de la même exécution de script.

Pour le visualiser je vous invite à executer :

Doctrine::getTable('myItem');
Doctrine::getTable('MyItem');
var_dump(Doctrine_Manager::getInstance());

XDEBUG est très fortement recommandé si vous ne voulez pas que le var_dump ne consomme toute votre mémoire.

Vous verrez alors :

  protected '_bound' => array
      'MyItem' => string  'doctrine' (length=8) 
      'myItemTranslation' => string 'doctrine' (length=8)

Vous pourrez constater que toute utilisation de MyItem, celui-ci ne trouvera pas sa table de Translation.
D’ou le message d’erreur qui explique qu’il ne parviens pas à trouver le champ traduit, car sans la table de Translation, Doctrine cherche le champ à l’interieur de l’objet lui même.

 

Filed under: Développement

Commentaires

un commentaire à “Doctrine 1.2, i18n : Column not found: 1054 Unknown column ‘h.translated_field’ in ‘field list’”
  1. kaore dit :

    La 2ème raison était la bonne dans mon cas. Pas évident à trouver: je viens de passer 1 bonne heure dessus.

    Merci pour ce post.

Répondre