Foros del Web » Programando para Internet » PHP » Zend »

[SOLUCIONADO] Asociaciones en doctrine 2

Estas en el tema de Asociaciones en doctrine 2 en el foro de Zend en Foros del Web. Hola: El concepto dice: una relacion bidireccional tiene un lado propietario y otro inverso en cambio el unidireccional solo tiene un lado propietario. Entonces el ...
  #1 (permalink)  
Antiguo 15/03/2013, 10:52
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Asociaciones en doctrine 2

Hola:

El concepto dice: una relacion bidireccional tiene un lado propietario y otro inverso en cambio el unidireccional solo tiene un lado propietario. Entonces el lado propietario determina las modificaciones de la relacion en la base de datos.

yo tengo la siguiente tabla departamento

Cita:
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| descripcion | varchar(200) | YES | | NULL | |
| departamento_id | int(4) | YES | | NULL | |
donde el lado propietario sería id y el inverso departamento_id las relaciones serían OneToMany bidireccional por lo que generé este modelo para representarlo:

Código PHP:
Ver original
  1. class Departamento
  2. {
  3.     /**
  4.      * @var integer
  5.      * @OneToMany(targetEntity="departamento", inversedBy="departamento_id")
  6.      * @JoinColumn(name="id", referencedColumnName="departamento_id")
  7.      *
  8.      * @Column(name="id", type="integer", nullable=false)
  9.      * @Id
  10.      * @GeneratedValue(strategy="IDENTITY")
  11.      */
  12.     private $id;
  13.     /**
  14.      * @var string
  15.      *
  16.      * @Column(name="descripcion", type="string", length=200, nullable=false)
  17.      */
  18.     private $descripcion;
  19.     /**
  20.      * @var integer
  21.      * @ManyToOne(targetEntity="departamento",mappedBy="id")
  22.      * @Column(name="departamento_id", type="integer", nullable=false)
  23.      */
  24.     private $departamentoId;
  25. ....
, tengo un mensaje de Creation Error en doctrine

Cita:
[Creation Error] The annotation @OneToMany declared on property Entities\Departamento::$id does not have a property named "inversedB
y". Available properties: mappedBy, targetEntity, cascade, fetch, orphanRemoval, indexBy
  #2 (permalink)  
Antiguo 15/03/2013, 11:13
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años
Puntos: 845
Respuesta: Asociaciones en doctrine 2

En el id tienes metadata de mas, la primer parte no iria, seria solamente

Código PHP:
Ver original
  1. /**
  2.  * @var integer $id
  3.  *
  4.  * @ORM\Column(name="id", type="integer")
  5.  * @ORM\Id
  6.  * @ORM\GeneratedValue(strategy="AUTO")
  7.  */
  8. protected $id;

y pregunto, que representa departamentId ?, self-referencing ?, en cualquier caso las propiedades relacionadas a una asociación no deberían tener como sufijo Id, no es una tabla es tu domain model, la propiedad debería ser simplemente $departamento
__________________
http://es.phptherightway.com/
thats us riders :)
  #3 (permalink)  
Antiguo 15/03/2013, 11:37
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Lo que trato de hacer es una relación OneToMany en la misma tabla, en algúnos manuales sugiere que para estos casos se establesca $id para la llave principal y nombredetabla_id seguido de "_id" para la secundaria.

Ahora según el manual de Doctrine las asociaiones son un punto fundamental para el mismo doctrine, que en este caso se trata de departamento, es decir, existirá un departamento denominado PRESIDENCIA y la cual tendrá como dependencias a las GERENCIAS y estas a su ves otras dependencias SUB-GERENCIAS, y la idea es que todo esté en una tabla, por lo que deduje que sería una asociacion Bidireccional OneToMany.

Valga la aclaración que antes de incorporar las asociaciones, estos modelos me generaban las tablas en MySQL.
  #4 (permalink)  
Antiguo 15/03/2013, 12:33
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años
Puntos: 845
Respuesta: Asociaciones en doctrine 2

Lo tienes en la doc OneToMany self-referencing
__________________
http://es.phptherightway.com/
thats us riders :)
  #5 (permalink)  
Antiguo 15/03/2013, 13:20
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Precisamente, siguiendo dicho manual, es que las asociaciones son OneToMany de la misma tabla departamento, pero me parece que ya solucioné el problema, auque tengo mis dudas puesto que las asociaciones no me los genera en el MySQL, imagino que lo debo realizar a mano.

este es el modelo:

Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace Entities;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8.  * Departamento
  9.  *
  10.  * @Table(name="departamento")
  11.  * @Entity
  12.  */
  13. class Departamento
  14. {
  15.     /**
  16.      * @var integer
  17.      * @ManyToOne(targetEntity="departamento", inversedBy="departamento_id")
  18.      * @JoinColumn(name="id", referencedColumnName="departamento_id")
  19.      *
  20.      * @Column(name="id", type="integer", nullable=false)
  21.      * @Id
  22.      * @GeneratedValue(strategy="IDENTITY")
  23.      */
  24.     private $id;
  25.  
  26.     /**
  27.      * @var string
  28.      *
  29.      * @Column(name="descripcion", type="string", length=200, nullable=false)
  30.      */
  31.     private $descripcion;
  32.  
  33.     /**
  34.      * @var string
  35.      *
  36.      * @Column(name="nombrecargousuario", type="string", length=200, nullable=false)
  37.      */
  38.     private $nombrecargousuario;
  39.  
  40.     /**
  41.      * @var integer
  42.      * @OneToMany(targetEntity="departamento",mappedBy="id")
  43.      *
  44.      * @Column(name="departamento_id", type="integer", nullable=false)
  45.      */
  46.     private $departamentoId;
  47.  
  48.     /**
  49.      * @var string
  50.      *
  51.      * @Column(name="sigla", type="string", length=50, nullable=false)
  52.      */
  53.     private $sigla;
  54.  
  55.     /**
  56.      * @var string
  57.      *
  58.      * @Column(name="formacite", type="string", length=20, nullable=false)
  59.      */
  60.     private $formacite;
  61.  
  62.     /**
  63.      * @var \DateTime
  64.      *
  65.      * @Column(name="fecha", type="date", nullable=false)
  66.      */
  67.     private $fecha;
  68.  
  69.     /**
  70.      * @var string
  71.      *
  72.      * @Column(name="estado", type="string", length=1, nullable=false)
  73.      */
  74.     private $estado;
  75.  
  76.     public function __construct() {
  77.         $this->departamentoId = new \Doctrine\Common\Collections\ArrayCollection();
  78.     }
  79. }

espero críticas o sugerencias
  #6 (permalink)  
Antiguo 15/03/2013, 14:00
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años
Puntos: 845
Respuesta: Asociaciones en doctrine 2

Te repito lo mismo, en id tienes metadata de mas y departamentoId debería ser departamento si es una unidad o bien departamentos si es una colección, luego en la metadata mapeas la clave foranea con el nombre que quieras pero a nivel de domain model es un objeto no el id del mismo.

Código PHP:
Ver original
  1. use Doctrine\Common\Collections\ArrayCollection;
  2.  
  3. /** @Entity **/
  4. class Departamento
  5. {
  6.  
  7.     /**
  8.      * @var integer
  9.      *
  10.      * @Column(name="id", type="integer", nullable=false)
  11.      * @Id
  12.      * @GeneratedValue(strategy="IDENTITY")
  13.      */
  14.     private $id;
  15.  
  16.     /**
  17.      * @var string
  18.      *
  19.      * @Column(name="descripcion", type="string", length=200)
  20.      */
  21.     private $descripcion;
  22.  
  23.     /**
  24.      * @OneToMany(targetEntity="Departamento", mappedBy="parent")
  25.      **/
  26.     private $children;
  27.  
  28.     /**
  29.      * @ManyToOne(targetEntity="Departamento", inversedBy="children")
  30.      * @JoinColumn(name="parent_id", referencedColumnName="id")
  31.      **/
  32.     private $parent;
  33.  
  34.     public function __construct()
  35.     {
  36.         $this->children = new ArrayCollection;
  37.     }
  38. }
__________________
http://es.phptherightway.com/
thats us riders :)

Última edición por masterpuppet; 15/03/2013 a las 14:05
  #7 (permalink)  
Antiguo 15/03/2013, 14:23
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Cita:
luego en la metadata mapeas la clave foranea con el nombre que quieras pero a nivel de domain model es un objeto no el id del mismo
Lo voy analizando, aunque se me hace algo dificil de comprenderlo sin embargo comparando con el manual de doctrine justifica lo que dices. debo seguir analizando

Muchas gracias.
  #8 (permalink)  
Antiguo 20/03/2013, 08:25
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

volviendo con el mismo ejemplo, se me fue algo complicado comprender el concepto pero creo que lo tengo: quisiera saber si este ejemplo esta bien: considerando que es self-referencing el lado propietario es parent y el inverso departamentos.

Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace Entities;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8.  * Departamento
  9.  *
  10.  * @Table(name="departamento")
  11.  * @Entity
  12.  */
  13. class Departamento
  14. {
  15.     /**
  16.      * @var integer
  17.      * @Column(name="id", type="integer", nullable=false)
  18.      * @Id
  19.      * @GeneratedValue(strategy="IDENTITY")
  20.      */
  21.     private $id;
  22.  
  23.     /**
  24.      * @var string
  25.      *
  26.      * @Column(name="descripcion", type="string", length=200, nullable=false)
  27.      */
  28.     private $descripcion;
  29.  
  30.     /**
  31.      * @OneToMany(targetEntity="Departamento", inversedBy="departamentos")
  32.      * @JoinColumn(name="departamento_id", referencedColumnName="id")
  33.      **/
  34.     private $parent;
  35.     /**
  36.      * @var string
  37.      *
  38.      * @Column(name="nombrecargousuario", type="string", length=200, nullable=false)
  39.      */
  40.     private $nombrecargousuario;
  41.  
  42.     /**
  43.      * @var integer
  44.      * @ManyToOne(targetEntity="Departamento",mappedBy="parent")
  45.      * @Column(name="departamento_id", type="integer", nullable=false)
  46.      *
  47.      * @Column(name="departamento_id", type="integer", nullable=false)
  48.      */
  49.     private $departamentos;
  50.  
  51.     /**
  52.      * @var string
  53.      *
  54.      * @Column(name="sigla", type="string", length=50, nullable=false)
  55.      */
  56.     private $sigla;
  57.  
  58.     /**
  59.      * @var string
  60.      *
  61.      * @Column(name="formacite", type="string", length=20, nullable=false)
  62.      */
  63.     private $formacite;
  64.  
  65.     /**
  66.      * @var \DateTime
  67.      *
  68.      * @Column(name="fecha", type="date", nullable=false)
  69.      */
  70.     private $fecha;
  71.  
  72.     /**
  73.      * @var string
  74.      *
  75.      * @Column(name="estado", type="string", length=1, nullable=false)
  76.      */
  77.     private $estado;
  78.  
  79.     public function __construct(){
  80.         $this ->departamentos = new \Doctrine\Common\Coollections\ArrayCollection();
  81.     }
  82. }

gracias
  #9 (permalink)  
Antiguo 20/03/2013, 11:33
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años
Puntos: 845
Respuesta: Asociaciones en doctrine 2

Supongo que no lo has probado, departamentos tiene metadata de mas(@Column, y duplicada), te sugiero que sigas el estándar para nombrar tus propiedades(lower camel case), un ej:

mal
Código PHP:
Ver original
  1. /**
  2.  * @var string
  3.  *
  4.  * @Column(name="nombrecargousuario", type="string", length=200, nullable=false)
  5.  */
  6. private $nombrecargousuario;

bien
Código PHP:
Ver original
  1. /**
  2.  * @var string
  3.  *
  4.  * @Column(name="nombre_cargo_usuario", length=200)
  5.  */
  6. private $nombreCargoUsuario;

Si prestas atención veras que en mi ejemplo hay menos metadata, el tipo por defecto es string y nullable false, si sigues las convenciones de Doctrine vas a escribir menos metadata ;)
__________________
http://es.phptherightway.com/
thats us riders :)
  #10 (permalink)  
Antiguo 26/03/2013, 10:07
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Crei que había solucionado mi problema sin embargo al generar entities me bota este error:

Cita:
[Creation Error] The annotation @OneToMany declared on property Entities\Departamento::$parent does not have a property named "inve
rsedBy". Available properties: mappedBy, targetEntity, cascade, fetch, orphanRemoval, indexBy
y estas son mi annotation
Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace Entities;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8.  * Departamento
  9.  *
  10.  * @Table(name="departamento")
  11.  * @Entity
  12.  */
  13. class Departamento
  14. {
  15.     /**
  16.      * @var integer
  17.      *
  18.      * @Column(name="id", type="integer", nullable=false)
  19.      * @Id
  20.      * @GeneratedValue(strategy="IDENTITY")
  21.      */
  22.     private $id;
  23.     /**
  24.      * @OneToMany(targetEntity="Departamento", inversedBy="departamentos")
  25.      * @JoinColumn(name="departamento_id", referencedColumnName="id")
  26.      **/
  27.     private $parent;
  28.  
  29.     /**
  30.      * @var \Departamento
  31.      *
  32.      * @ManyToOne(targetEntity="Departamento",mappedBy="parent")
  33.      * @JoinColumns({
  34.      *   @JoinColumn(name="departamento_id", type="integer")
  35.      * })
  36.      */
  37.     private $departamentos;
  38.  
  39.     /**
  40.      * @var string
  41.      *
  42.      * @Column(name="estado", type="string", length=1, nullable=false)
  43.      */
  44.     private $estado;
  45.  
  46.     public function __construct(){
  47.         $this ->departamentos = new \Doctrine\Common\Coollections\ArrayCollection();
  48.     }
  49.  
  50. }
el mensaje esta claro pero no se exactamento por que
  #11 (permalink)  
Antiguo 26/03/2013, 21:40
Avatar de carlos_belisario
Colaborador
 
Fecha de Ingreso: abril-2010
Ubicación: Venezuela Maracay Aragua
Mensajes: 3.156
Antigüedad: 9 años, 9 meses
Puntos: 461
Respuesta: Asociaciones en doctrine 2

mira la referencia
http://docs.doctrine-project.org/en/...-bidirectional
el error claramente te dice que el OneToMany no maneja una propiedad inversedBy, si mal no recuerdo debería de ser
Código PHP:
Ver original
  1. /**
  2.      *
  3.      * @OneToMany(targetEntity="Children", mappedBy="departamentos")    
  4.      **/
  5.     private $parent;
saludos
__________________
aprende d tus errores e incrementa tu conocimientos
it's not a bug, it's an undocumented feature By @David
php the right way
  #12 (permalink)  
Antiguo 27/03/2013, 08:42
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Carlos tienes toda la razon, pero entonces que hago con el concepto que en mi caso es una referencia en la misma tabla donde el id es el unico que puede tener muchos hijos (departamento_id), el concepto sería erroneo si decimos que (departamento_id) es uno a muchos (que en este caso es id), para mi el concepto OneToMany y ManyToOne es:

OneToMany
id to departamento_id

ManyToOne
departamento_id to id

para esto uso parent, por favor agradeceré mucho tu ayuda en aclararme este tema.
  #13 (permalink)  
Antiguo 27/03/2013, 09:06
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 12 años
Puntos: 845
Respuesta: Asociaciones en doctrine 2

Tienes cambiado el mapeo, comprueba el ejemplo de self referencing de la documentación, es exactamente lo mismo.
__________________
http://es.phptherightway.com/
thats us riders :)
  #14 (permalink)  
Antiguo 28/03/2013, 11:11
 
Fecha de Ingreso: enero-2010
Mensajes: 491
Antigüedad: 10 años
Puntos: 12
Respuesta: Asociaciones en doctrine 2

Muchas gracias por su colaboración

Etiquetas: doctrine
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:01.