IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Doctrine constrainte violation sur composite fk


Sujet :

Symfony PHP

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 29
    Par défaut Doctrine constrainte violation sur composite fk
    Bonjour,

    Je dispose de 3 entités liées : Famille - SousFamille - Produit

    Une Famille à 0-n SousFamille
    Un Produit à 1-1 Famille
    Un Produit à 0-1 SousFamille

    La clé primaire sur SousFamille est composée ( sousfamille.id, sousfamille.famille_id )

    Voici les 3 entités :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /**
     * Famille
     *
     * @ORM\Table(name="famille")
     * @ORM\Entity
     */
    class Famille
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        private $id;
     
        /**
         * @var string
         *
         * @ORM\Column(name="designation", type="string", length=50, nullable=true)
         */
        private $designation;
     
        /**
         * @ORM\OneToMany(targetEntity="SousFamille", mappedBy="famille", cascade={"persist", "remove"})
         */
        protected $sousFamilles;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    /**
     * SousFamille
     *
     * @ORM\Table(name="sousfamille")
     * @ORM\Entity
     */
    class SousFamille
    {
        /**
         * @var integer
         *
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="NONE")
         * @ORM\Column(name="id", type="integer", nullable=false)
         */
        private $id;
     
        /**
         * @var \Famille
         *
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="NONE")
         * @ORM\ManyToOne(targetEntity="Famille", inversedBy="sousFamilles")
         * @ORM\JoinColumn(name="famille_id", referencedColumnName="id", nullable=false)
         */
        private $famille;
     
        /**
         * @var string
         *
         * @ORM\Column(name="designation", type="string", length=50, nullable=true)
         */
        private $designation;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    /**
     * Produit
     *
     * @ORM\Table(name="produit")
     * @ORM\Entity(repositoryClass="Eliance\PrestaBundle\Entity\Repository\ProduitRepository")
     */
    class Produit
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        protected $id;
     
        // ...
     
        /**
         * @var \Famille
         *
         * @Assert\NotBlank()
         * @ORM\ManyToOne(targetEntity="Famille")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="famille_id", referencedColumnName="id", nullable=false)
         * })
         */
        protected $famille;
     
        /**
         * @var \SousFamille
         *
         * @ORM\ManyToOne(targetEntity="SousFamille")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="sousfamille_id", referencedColumnName="id", nullable=true),
         *   @ORM\JoinColumn(name="famille_id", referencedColumnName="famille_id")
         * })
         */
        protected $sousFamille;
    Voici une pseudo représentation des données attendues :

    +-----------------+
    |     FAMILLE     |
    +-----------------+
    |  id             |
    +-----------------+
    | A               |
    | B               |
    | C               |
    +-----------------+
    +-----------------+
    |   SOUSFAMILLE   |
    +-----------------+
    | famille_id | id |
    +-----------------+
    | A          | A1 |
    | A          | A2 |
    | B          | B1 |
    +-----------------+
    +----------------------------------+
    |             PRODUIT              |
    +----------------------------------+
    | id | famille_id | sousfamille_id |
    +----------------------------------+
    | P1 | A          | A2             |
    | P2 | B          | B1             |
    | P3 | C          | null           |
    +----------------------------------+
    Mon problème concerne le produit "P3".

    Dans le formulaire je choisi donc une famille et pas de sous-famille.
    Lors de la soumission du formulaire, dans le controller juste avant d'exécuter le flush, mon entité Produit dispose bien d'une entité Famille (et n'a pas d'entité SousFamille).

    Par contre durant l'exécution de la méthode flush Doctrine semble supprimer l'objet Famille car j'obtiens une magnifique violation de contrainte :
    Integrity constraint violation: 1048 Column 'famille_id' cannot be null
    En effet si on observe l'insert généré par Doctrine la value pour famille_id est bien null, alors qu'on l'avais spécifiée

    Capture du debuger

    Nom : xdebug.png
Affichages : 146
Taille : 72,9 Ko


    Infos supplémentaires :

    . Pas de problème si Famille + SousFamille sont renséignées
    . Dans mon FormType Produit, 'famille' et 'sousfamille' sont de type entity


    Merci de vos lumières car la je sèche complétement
    ( Je me doute que Doctrine priorise la 'famille_id' de l'entité SousFamille mais pourquoi ? comment y remédier ? )

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Février 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 29
    Par défaut
    Apparemment l'ORM lit les propriétés de façon séquentielle et construit la requête.
    En inversant dans Produit les propriétés famille et sousFamille (sousFamille avant famille), famille_id de SousFamille n'écrase plus id de Famille.
    La value est correctement ajoutée dans la requête insert.

    Par contre à mon sens c'est une solution "bricolage". Si vous avez connaissance d'une solution plus pérenne je suis preneur.

Discussions similaires

  1. Réponses: 11
    Dernier message: 09/07/2014, 17h22
  2. Access Violation sur un delete
    Par devroot dans le forum C++
    Réponses: 11
    Dernier message: 29/09/2007, 23h22
  3. Access violation sur un new
    Par cedekasme dans le forum C++Builder
    Réponses: 16
    Dernier message: 23/01/2007, 14h32
  4. Protocol violation sur Oracle avec hibernate
    Par francois.chapuzot dans le forum Hibernate
    Réponses: 1
    Dernier message: 04/08/2006, 08h33
  5. [Imp]"unique constraint violated" sur un import
    Par u_roisin dans le forum Oracle
    Réponses: 10
    Dernier message: 16/02/2006, 10h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo