/**
  * Obtiene solo una asociacion.
  */
 public function get_many_assoc_lazy(PersistentObject $obj, $hmattr)
 {
     Logger::getInstance()->pm_log("PM.get_many_assoc_lazy " . get_class($obj) . " " . $hmattr);
     // TODO: tengo que cargar solo si tiene deleted en false en la tabla de join.
     // FIXME: esta clase podria ser superclase de la subclase que quiero cargar.
     //        tengo que ver en la tabla de que tipo es realmente y cargar una instancia de eso.
     $hmattrClazz = $obj->getAttributeType($hmattr);
     // (***)
     $relObjIns = new $hmattrClazz();
     // Intancia para hallar nombre de tabla.
     $relObjTableName = YuppConventions::tableName($relObjIns);
     $relTableName = "";
     $obj_is_owner = $obj->isOwnerOf($hmattr);
     if ($obj_is_owner) {
         $relTableName = YuppConventions::relTableName($obj, $hmattr, $relObjIns);
     } else {
         // Si no soy owner tengo que pedir el atributo...
         $ownerInstance = $relObjIns;
         // FIXME: si ownerInstance tiene 2 relaciones HM con la class del $obj, este metodo retorna NULL.
         $ownerAttrNameOfSameAssoc = $ownerInstance->getHasManyAttributeNameByAssocAttribute(get_class($obj), $hmattr);
         //echo "Call to relTableName hmattr=$hmattr ownerAttr=$ownerAttrNameOfSameAssoc ".__FILE__.__LINE__."<br/>";
         $relTableName = YuppConventions::relTableName($ownerInstance, $ownerAttrNameOfSameAssoc, $obj);
     }
     // =================================================================================
     // (***)
     // FIXME: deberia hacer un join con la tabla de referencia y la
     //        tabla destino para traer todos los atributos y no tener
     //        que hacer consultas individuales para cargar cada objeto.
     //
     // =================================================================================
     // =================================================================================
     // QIERO PEDIR SOLO LOS ELEMENTOS DE ObjectReference, para poder recorrerlo y ver si ya tengo objetos cargados,
     // y cargo solo los que no estan cargados. Seteo todos los objetos al atributo hasMany del objeto.
     YuppLoader::load('core.db.criteria2', 'Query');
     $q = new Query();
     $q->addFrom($relTableName, 'ref');
     // person_phone ref // FIXME: ESTO ES addFrom.
     $q->addFrom($relObjTableName, 'obj');
     // FIXME: quiero todos los atributos...
     // Se agregan los atributos de la clase como proyeccion de la query.
     // Solo quiero los atributos de OBJ, agrego sus atributos como proyecciones de la consulta.
     /* esto seleccionaba solo los atributos declarados en la clase.
        foreach( $_obj->getAttributeTypes() as $attr => $type )
        {
           //$q->addProjection("obj", $attr);
           // TODO: normalizar en la query mismo
           $q->addProjection( "obj", DatabaseNormalization::col($attr) );
        }
        */
     $q->addProjection('obj', '*');
     // Todos los atributos de la tabla con alias "obj".
     // Necesito saber el nombre del atributo de los ids asociados.
     $hm_assoc_attr = "owner_id";
     // FIXME: poner el string en una clase de convensiones de yupp
     // Los ids de todas las instnacias parciales de la clase declarada en el atributo
     // hasMany, van a ser todos iguales, por eso uso el id del objeto que viene.
     $obj_id = $obj->getId();
     // Tengo que ver el objeto en la tabla de referehcia si es el owner_id o el ref_id
     if ($obj_is_owner) {
         // FIXME: poner el string en una clase de convensiones de yupp
         $hm_assoc_attr = 'ref_id';
         // yo soy el owner entonces el asociado es ref.
         $q->setCondition(Condition::_AND()->add(Condition::EQ('ref', 'owner_id', $obj_id))->add(Condition::EQA('obj', 'id', 'ref', 'ref_id')));
     } else {
         $q->setCondition(Condition::_AND()->add(Condition::EQ('ref', 'ref_id', $obj_id))->add(Condition::EQ('ref', 'type', ObjectReference::TYPE_BIDIR))->add(Condition::EQA('obj', 'id', 'ref', 'owner_id')));
     }
     // ==========================================================================
     // Desde v0.1.6: soporte para tipos de hasMany
     // Si es de tipo lista, debe donsiderar el orden.
     if ($obj->getHasManyType($hmattr) === PersistentObject::HASMANY_LIST) {
         $q->addOrder("ref", "ord", "ASC");
         // Orden ascendente por atributo ORD de la tabla intermedia.
     }
     Logger::getInstance()->pm_log("PersistentManager.get_many_assoc_lazy query " . __FILE__ . " " . __LINE__);
     // Trae todos los objetos linkeados... (solo sus atributos simples)
     $data = $this->dal->query($q);
     // FIN QUERY...
     $wasDirty = $obj->isDirtyMany();
     // Ojo, se prenden bits de dirty (es necesario detectar si no estaba dirty antes, para saber si puede limpiar).
     $obj->aSet($hmattr, array());
     // Inicalizo lista xq seguramente estaba en NOT_LOADED.
     foreach ($data as $many_attrValues) {
         /* Esta cargado?
          * $rel_obj_id = $many_attrValues[ $hm_assoc_attr ]; // El codigo que usa esta linea esta comentado...
          * if ( ArtifactHolder::getInstance()->existsModel( $hmattrClazz, $rel_obj_id ) )
          * {
          *    $rel_obj = ArtifactHolder::getInstance()->getModel( $hmattrClazz, $rel_obj_id );
          * }
          * else
          * {
          *    $rel_obj = $this->get_object( $hmattrClazz, $rel_obj_id ); // Carga solo el objeto, sin asociaciones.
          *    ArtifactHolder::getInstance()->addModel( $rel_obj ); // FIXME: ArtHolder deberia referenciarse solo del PM!!!!!
          * }
          */
         // Esto soluciona la carga de autorrelacion desde una subclase.
         // B(heredaDe)A y A(hasMany)A, y quiero cargar B que a su vez tiene asociados varios Bs.
         // FIXME: esta clase podria ser superclase de la subclase que quiero cargar.
         //        tengo que ver en la tabla de que tipo es realmente y cargar una instancia de eso.
         // (***)
         //$rel_obj = $this->createObjectFromData( $hmattrClazz, $many_attrValues );
         if ($many_attrValues['class'] === $hmattrClazz) {
             // FIXME: si el rel_obj tiene hasOne, y hereda de otra clase, no se cargan los hasOne.
             //Logger::getInstance()->pm_log("Caso1: $hmattrClazz ". __FILE__ ." ". __LINE__);
             //Logger::struct($many_attrValues, "many_attrValues");
             //echo "   la clase es la misma que la declarada<br/>";
             $rel_obj = $this->createObjectFromData($hmattrClazz, $many_attrValues);
         } else {
             //Logger::getInstance()->pm_log("Caso2: [$hmattrClazz / ". $many_attrValues['class'] ."] " . __FILE__ ." ". __LINE__);
             //Logger::struct($many_attrValues, "many_attrValues");
             //echo "   la clase NO es la misma que la declarada<br/>";
             // TODO: deberia cargar los atributos declarados en la clase $many_attrValues['class'], que estan en otra tabla que la que acabo de cargar.
             //       por ejemplo el id cargado es el de una superclase no el de la clase que deberia ser la instancia.
             $rel_obj = $this->get_mti_object_byData($hmattrClazz, $many_attrValues);
         }
         $obj->aAddTo($hmattr, $rel_obj);
     }
     if (!$wasDirty) {
         $obj->resetDirtyMany();
     }
 }