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

Doctrine 2 Symfony2

Estas en el tema de Doctrine 2 Symfony2 en el foro de Symfony en Foros del Web. Hola, que tal ¿? Estoy haciendo un proyecto en Symfony2. con Symfony2 y Twig todo muy bonito :) pero el problema va más por el ...
  #1 (permalink)  
Antiguo 21/09/2011, 15:51
 
Fecha de Ingreso: enero-2009
Mensajes: 24
Antigüedad: 15 años, 9 meses
Puntos: 1
Doctrine 2 Symfony2

Hola, que tal ¿?

Estoy haciendo un proyecto en Symfony2.

con Symfony2 y Twig todo muy bonito :)

pero el problema va más por el lado de Doctrine 2.1

Leyendo un poco las asociaciones, me estoy complicando un poco...

Por ejemplo:

Tengo dos Tablas: y la asociación se Bidireccional.

Entidad PostCategory

Código PHP:

namespace LmsPostBundleEntity
;

use 
DoctrineORMMapping as ORM;
use 
SymfonyComponentValidatorConstraints as Assert;
use 
DoctrineCommonCollectionsArrayCollection;

/**
 * Lms\PostBundle\Entity
 *
 * @ORM\Table(name="postcategory")
 * @ORM\Entity(repositoryClass="Lms\PostBundle\Entity\PostCategoryRepository")
 */
class PostCategory
{

   
/**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue(strategy="IDENTITY")
    */
    
protected $id;

   
/**
    * @ORM\Column(type="string")
    */
    
protected $name;
    
    
   
/**
    * @ORM\OneToMany(targetEntity="Post", mappedBy="postcategory")
    */
    
protected $posts;
    
    public function 
__construct()
    {
        
$this->posts = new ArrayCollection();
    }


    
/**
     * Get idpostcategory
     *
     * @return integer 
     */
    
public function getId()
    {
        return 
$this->id;
    }
  

    
/**
     * Set name
     *
     * @param datetime $name
     */
    
public function setName($name)
    {
        
$this->name $name;
    }

    
/**
     * Get name
     *
     * @return datetime 
     */
    
public function getName()
    {
        return 
$this->name;
    }

    
/**
     * Add posts
     *
     * @param Lms\PostBundle\Entity\Post $posts
     */
    
public function addPost(LmsPostBundleEntityPost $posts)
    {
        
$this->posts[] = $posts;
    }

    
/**
     * Get posts
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    
public function getPosts()
    {
        return 
$this->posts;
    }

Entidad Post

Código PHP:


namespace LmsPostBundleEntity
;

use 
DoctrineORMMapping as ORM;
use 
SymfonyComponentValidatorConstraints as Assert;
use 
DoctrineCommonCollectionsArrayCollection;
use 
SymfonyComponentValidatorMappingClassMetadata;
use 
SymfonyComponentValidatorConstraintsNotBlank;


/**
 * Lms\PostBundle\Entity
 *
 * @ORM\Table(name="post")
 * @ORM\Entity(repositoryClass="Lms\PostBundle\Entity\PostRepository")
 */
class Post
{

   
/**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue(strategy="IDENTITY")
    */
    
protected $idpost;
    
   
/**
    *
    * @ORM\Column(type="string") 
    */
    
protected $subject;
    
    
/**
    * @ORM\Column(type="integer")
    */  
    
protected $idpostcategory;
    
    
/**
     * @ORM\ManyToOne(targetEntity="PostCategory", inversedBy="posts", cascade={"remove"})
     * @ORM\JoinColumn(name="idpostcategory", referencedColumnName="id")
     */
    
protected $postcategory;
    

    
/**
     * Get idpost
     *
     * @return integer 
     */
    
public function getIdpost()
    {
        return 
$this->idpost;
    }

    
/**
     * Set subject
     *
     * @param string $subject
     */
    
public function setSubject($subject)
    {
        
$this->subject $subject;
    }

    
/**
     * Get subject
     *
     * @return string 
     */
    
public function getSubject()
    {
        return 
$this->subject;
    }


    

    
/**
     * Set idpostcategory
     *
     * @param integer $idpostcategory
     */
    
public function setIdpostcategory($idpostcategory)
    {
        
$this->idpostcategory $idpostcategory;
    }

    
/**
     * Get idpostcategory
     *
     * @return integer 
     */
    
public function getIdpostcategory()
    {
        return 
$this->idpostcategory;
    }

    
/**
     * Set postcategory
     *
     * @param Lms\PostBundle\Entity\PostCategory $postcategory
     */
    
public function setPostcategory(LmsPostBundleEntityPostCategory $postcategory)
    {
        
$this->postcategory $postcategory;
    }

    
/**
     * Get postcategory
     *
     * @return Lms\PostBundle\Entity\PostCategory 
     */
    
public function getPostcategory()
    {
        return 
$this->postcategory;
    }


En ese efecto el Inner Join con DQL me funciona perfecto !
La insercción de las dos tablas me funciona perfecto también!

Por ejemplo:

Código PHP:

       $categories 
= new PostCategory();
        
$categories->setName('Nueva Categoria !');
        
        
$post = new Post();
        
$post->setSubject('Nuevo Post');
        
        
$post->setPostcategory($categories);

        
$em $this->get('doctrine')->getEntityManager();
        
$em->persist($categories);
        
$em->persist($post);
        
$em->flush(); 
        
        echo 
$post->getIdpost();
        
        exit(); 
1. Pero mi problema es, como inserto la tabla POST sin la necesidad de insertar la tabla Padre, PostCategory;

2. Hay alguna manera más fácil de trabajar o este es el único modo?

3. Al final los beneficios son grandes? me refiero al tiempo, performance, rendimiento.

4. eh tratado de insertar la tabla Post de todas formas pero no me sale, cual creen que sea el problema?
  #2 (permalink)  
Antiguo 21/09/2011, 17:03
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Doctrine 2 Symfony2

1) y 4)
Tienes que tener en cuenta lo que sucede a un nivel inferior en la bbdd, estas intentado insertar un registro sin la clave foránea correspondiente, no es un problema de doctrine, es el comportamiento normal del rdbms, una solucion seria One-To-Many, Unidirectional with Join Table(que en definitiva es un @ManyToMany).
Y te hago un par de comentarios/sugerencias, tienes una propiedad Post::idpostcategory, porque razón ?, si ya tienes la asociacion con Post y a partir de ella puedes obtener el id y la propiedad Post::idpost debería ser simplemente Post::id.

2) mas sencillo que crear dos objetos setear un par de propiedades y hacer un persist - flush ?, que tiene de complejo ?

3) realmente no ves los beneficios ?, sobre peformance y rendimiento te dejo unas referencias

http://www.doctrine-project.org/blog...ance-revisited
http://www.doctrine-project.org/blog...ng-mythbusters
http://www.doctrine-project.org/blog...nd-performance

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #3 (permalink)  
Antiguo 21/09/2011, 17:35
 
Fecha de Ingreso: enero-2009
Mensajes: 24
Antigüedad: 15 años, 9 meses
Puntos: 1
Respuesta: Doctrine 2 Symfony2

Hola gracias por contestar.

1. Entonces la solución es cambiar mi Modelo y hacer un puente de muchos a muchos?

2. Me sugieres que tenga en todas las tablas a los identificadores con id y si es una tabla has manytomany recien post_id, postcategory_id

3. No lo decía por el echo de ser complejo en el sentido de ahora, si no, que pasaría si por ejemplo tengo un modelo de 100 tablas ya echas? las tengo que modificar para darle sentido a doctrine?

Esa sería la única solución?, osea no puedo insertar la tabla post ni siquiera poniendo un ID existente de prueba en el mismo código?, por que en el mysql me funciona normal....

Gracias,
Michel.
  #4 (permalink)  
Antiguo 21/09/2011, 18:27
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Doctrine 2 Symfony2

1 - Si la categoría es opcional si, es un ManyToMany con el id del post en la relación como unique.
2 - Lo que te sugiero es que a las propiedades no les agregues el nombre de la clase, esto es redundante:

Código PHP:
Ver original
  1. class Post
  2. {
  3.  
  4.    /**
  5.     * @ORM\Id
  6.     * @ORM\Column(type="integer")
  7.     * @ORM\GeneratedValue(strategy="IDENTITY")
  8.     */
  9.     protected $idpost;
  10.    ...
  11. }

en la clase Post declaras la propiedad idpost, es mas claro si simplemente la llamas id:

Código PHP:
Ver original
  1. class Post
  2. {
  3.  
  4.    /**
  5.     * @ORM\Id
  6.     * @ORM\Column(type="integer")
  7.     * @ORM\GeneratedValue(strategy="IDENTITY")
  8.     */
  9.     protected $id;
  10. }

algo similar con la categoría,

Código PHP:
Ver original
  1. class Post
  2. {
  3.    ...    
  4.     /**
  5.      * @ORM\ManyToOne(targetEntity="PostCategory", inversedBy="posts", cascade={"remove"})
  6.      * @ORM\JoinColumn(name="idpostcategory", referencedColumnName="id")
  7.      */
  8.     protected $postcategory;
  9. }

un post tiene una categoria, es mas claro:

Código PHP:
Ver original
  1. class Post
  2. {
  3.    ...  
  4.     /**
  5.      * @ORM\ManyToOne(targetEntity="PostCategory", inversedBy="posts", cascade={"remove"})
  6.      */
  7.     protected $category;
  8.  
  9. }

si prestas atencion veras que elimine @JoinColumn, utilízalo solamente cuando quieras personalizar algo, sino deja que doctrine se encargue, si sigues sus convenciones vas a escribir menos código .

3 - Si tienes un schema ya echo y a partir de este quieres utilizar doctrine tendrás que ajustar de las dos partes, pero doctrine no esta pensado para crear primero la bbdd y luego montar el domain model, sino que todo lo contrario, lo importante es el domain model, la bbdd no es mas que persistencia.

Cita:
Esa sería la única solución?, osea no puedo insertar la tabla post ni siquiera poniendo un ID existente de prueba en el mismo código?, por que en el mysql me funciona normal....
mysql(innodb) te deja insertar un registro sin la clave foránea correspondiente ?, en cuanto al insert si conoces el id puedes utilizar EntityManager#getReference, algo asi:

Código PHP:
Ver original
  1. $em = $this->get('doctrine')->getEntityManager();
  2.  
  3. $post = new Post();
  4. $post->setSubject('Nuevo Post');
  5. $post->setCategory($em->getReference('PostCategory', 1));
  6.  
  7. $em->persist($post);
  8. $em->flush();

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #5 (permalink)  
Antiguo 21/09/2011, 20:14
 
Fecha de Ingreso: enero-2009
Mensajes: 24
Antigüedad: 15 años, 9 meses
Puntos: 1
Respuesta: Doctrine 2 Symfony2

Aja! Gracias ! haha ya me está gustando!

Alguna sugerencia más por el lado de convenciones para no tener que lidear con los joins en las entidades?.

Por ejemplo ahora toca hacer un ManyToMany, voy a tratar de probar como insertaría la tabla del medio, aunque por lo que estoy
leyendo doctrine te hace por ti, pero que tal si aparte de las dos foraneas tengo un campo más titulo? voy a ver que tal como me va!

Saludos.

Última edición por MichaelParra; 21/09/2011 a las 20:22
  #6 (permalink)  
Antiguo 22/09/2011, 02:14
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Doctrine 2 Symfony2

Las convenciones las tienes en Mapping Defaults.

Y de la "tabla del medio" a no ser que tenga mas campos no te tienes que preocupar, doctrine lo maneja por ti, y en el caso de tener campos, creas una entidad para la relación, el @ManyToMany pasa a ser un @OneToMany - @ManyToOne doble(uno para cada entidad del anterior @ManyToMany).

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #7 (permalink)  
Antiguo 08/12/2011, 17:33
 
Fecha de Ingreso: noviembre-2011
Ubicación: peru
Mensajes: 7
Antigüedad: 13 años
Puntos: 0
Respuesta: Doctrine 2 Symfony2

hola amigos

hice la "tabla del medio" porque necesito añadir un campo mas al detalle pero me genera el error (no identificado el primary key de la entidad) , segui .. @OneToMany - @ManyToOne , pero me sale ese error...
que puedo hacer?

gracias por su respuesta
  #8 (permalink)  
Antiguo 08/12/2011, 17:34
Avatar de carlos_belisario
Colaborador
 
Fecha de Ingreso: abril-2010
Ubicación: Venezuela Maracay Aragua
Mensajes: 3.156
Antigüedad: 14 años, 7 meses
Puntos: 461
Respuesta: Doctrine 2 Symfony2

bienvenido al foro, seria bueno que crees un tema con tu duda y nos expongas lo que tienes hecho porque así adivinando es un poco dificil, 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
  #9 (permalink)  
Antiguo 08/12/2011, 18:05
 
Fecha de Ingreso: noviembre-2011
Ubicación: peru
Mensajes: 7
Antigüedad: 13 años
Puntos: 0
Respuesta: Doctrine 2 Symfony2

como mi duda va relacionado a este tema pense que podia continuarlo.

solo queria una referencia de como añadir un campo al detalle que tengo de dos tablas, hice una entidad a mi detalle para poder agregar un campo mas (lo recomendado por masterpuppet ), pero en ese intento me salio el error mencionado.
  #10 (permalink)  
Antiguo 08/12/2011, 18:08
Avatar de carlos_belisario
Colaborador
 
Fecha de Ingreso: abril-2010
Ubicación: Venezuela Maracay Aragua
Mensajes: 3.156
Antigüedad: 14 años, 7 meses
Puntos: 461
Respuesta: Doctrine 2 Symfony2

por lo mismo te indico que necesitamos mas detalles, incluso ver las entitys, ya que el error que te indica es muy simple que es que no tienes PK en la entidad, incluso creo que pudiera ser porque estas haciendo una FK de un campo que no es indice y eso el manejador de DB que estes usando lo toma como un error
__________________
aprende d tus errores e incrementa tu conocimientos
it's not a bug, it's an undocumented feature By @David
php the right way
  #11 (permalink)  
Antiguo 08/12/2011, 18:48
 
Fecha de Ingreso: noviembre-2011
Ubicación: peru
Mensajes: 7
Antigüedad: 13 años
Puntos: 0
Respuesta: Doctrine 2 Symfony2

muy bien ya publique el tema

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 10:13.