2010-07-25 12 views
9

leí documentación oficial y un montón de hilos, pero todavía no encuentro solución para mi situación. Mi caso es muy básico. Tengo 2 entidades: comentarios y palabras clave para ellos. Un comentario puede tener muchas palabras clave, pero cada palabra clave es solo para un comentario. Las palabras clave no son únicas en la tabla de palabras clave. Así que decidí que esta es una relación de uno a muchos. estructura de las tablas son simplemente gustaría sigue:problema para entender la cartografía relación en la doctrina 2

palabras clave

id   int(11) 
comment_id int(11) 
text  varchar(30) 

comentarios

id  int(11) 
text text 

aquí es cómo ellos mapeado:


/** 
* @Entity 
* @Table(name="comments") 
**/ 
class Comments 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 
    /** @Column(type="text") */ 
    private $text; 

    /** 
    * @OneToMany(targetEntity="keywords", mappedBy="comment_id") 
    */ 
    private $keywords; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
    public function getKeywords(){return $this->keywords;} 
} 
/** 
* @Entity 
* @Table(name="keywords") 
*/ 

class Keywords 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    private $text; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
} 
 

y cómo utilizarlo es la siguiente:


$comments = $this->em->getRepository('comments')->findAll(); 
foreach($comments as $comment){ 
    foreach($comment->getKeywords() as $keyword){ 
     $keyword->getText(); 
    } 
}

y consiguió esta errores:

 
Notice: Undefined index: comment_id in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1096 
Notice: Trying to get property of non-object in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1098 
Warning: Invalid argument supplied for foreach() in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1098 
Notice: Undefined index: comment_id in C:\web_includes\doctrine\ORM\PersistentCollection.php on line 168 
Fatal error: Call to a member function setValue() on a non-object in C:\web_includes\doctrine\ORM\PersistentCollection.php on line 169 
Cuál es el problema? ¿Dónde debería definir comment_id? ¿Mi mapeo es correcto? Realmente me quedé atrapado y necesito ayuda, por favor, cualquier consejo es bienvenido.

+0

¿qué pasa con 'comment_id'? ¿cómo se establece la relación entre los comentarios y las palabras clave? – Sadat

+0

comment_id es un campo en la base de datos en la tabla de palabras clave que tienen id del comentario esta palabra clave pertenece. Supongo que la doctrina lo usará al seleccionar palabras clave para comentarios. relación es así OneToMany (targetEntity = "palabras clave", mappedBy = "comment_id") ¿es correcto? – SET

Respuesta

13

El atributo mappedBy Qué dice nada sobre el nombre de la clave externa, Eso es lo que la anotación "@JoinColumn" es para. La asignación correcta para este escenario sería:

/** 
* @Entity 
* @Table(name="comments") 
**/ 
class Comments 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 
    /** @Column(type="text") */ 
    private $text; 

    /** 
    * @OneToMany(targetEntity="keywords", mappedBy="comment") 
    */ 
    private $keywords; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
    public function getKeywords(){return $this->keywords;} 
} 

/** 
* @Entity 
* @Table(name="keywords") 
*/ 
class Keywords 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    /** 
    * @ManyToOne(targetEntity="Comments", inversedBy="keywords") 
    */ 
    private $comment; 

    /** 
    * @Column(type="text") */ 
    private $text; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
} 

Uso de la herramienta de esquema que genera el SQL que es igual a su esquema:

CREATE TABLE comments (id INT NOT NULL, text LONGTEXT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
CREATE TABLE keywords (id INT NOT NULL, comment_id INT DEFAULT NULL, text LONGTEXT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
ALTER TABLE keywords ADD FOREIGN KEY (comment_id) REFERENCES comments(id); 

Dos problemas en su asignación:

  1. Tienes que entender la diferencia entre poseer y lado inverso. El simple hecho de tener una relación unidireccional de Uno a Muchos requiere una tercera tabla de unión. Sin embargo, con una relación bidireccional como en mi mapeo con la propiedad del lado propietario Keyword :: $ comment funciona.
  2. "mappedBy" se refiere a la propiedad en el otro targetEntity que es "el otro lado de esta asociaciones". InversedBy tiene el mismo significado, solo que invertedBy siempre se especifica en el lado propietario, mappedBy en el lado inverso.

Todo esto suena muy complicado, pero es una forma muy eficiente desde la perspectiva técnica de ORMs, ya que permite actualizar las asociaciones con el menor número de instrucciones SQL UPDATE necesarias. Consulte la documentación sobre cómo funciona la inversa/Ser propietario:

http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en#owning-side-and-inverse-side

+0

¡ESO REALMENTE FUNCIONA! Muchas gracias. Pero tengo que preguntar cuál es la diferencia entre las relaciones unidireccionales y las bidireccionales.Además, qué entidad en mi caso será inversa y qué será propietaria. Supongo que comentar en poseer y keywodrs es inverso, pero no puedo decir por qué. – SET

+0

Palabras clave es el lado propietario, porque la clave externa "comment_id" está en la tabla de palabras clave. Unidireccional significa que solo puede caminar de Comment to Keywords, usando Comment :: getKeywords(). Bidireccional significa que puede ir en ambas direcciones con la palabra clave adicional :: getComment() (falta en mi ejemplo). El capítulo de asociación es bastante extenso, pero debe leer los capítulos "Trabajar con asociaciones" y "Asignaciones de asociación" para obtener todo el concepto. – beberlei

Cuestiones relacionadas