简体   繁体   English

在 Symfony 2 中使用多对多双向关系保存数据

[英]Persist data with a ManyToMany bidirectionnal relation in Symfony 2

I have a many to many relation between 2 entities : Agent & Habilitation.我有 2 个实体之间的多对多关系:Agent & Habilitation。 I get an error on the form validation :我收到表单验证错误:

Could not resolve type of column "id" of class "CNAMTS\\RAVC\\Bundle\\Entity\\Agent"无法解析类“CNAMTS\\RAVC\\Bundle\\Entity\\Agent”的列“id”的类型

At the beginning, my Agent and Habilitation $id were $ageId and $habId, but I already had same error.一开始,我的 Agent 和 Habilitation $id 是 $ageId 和 $habId,但我已经有同样的错误。 I had try to change for just $id in both entities, but I'm still getting this error.我曾尝试在两个实体中仅更改 $id,但我仍然收到此错误。

Also get error when I'm doing a doctrine:schema:validate当我在做一个doctrine:schema:validate时也会出错doctrine:schema:validate

[Mapping] FAIL - The entity-class 'CNAMTS\\RAVC\\Bundle\\Entity\\Agent' mapping is invalid: [映射] 失败 - 实体类“CNAMTS\\RAVC\\Bundle\\Entity\\Agent”映射无效:

  • The referenced column name 'id' has to be a primary key column on the target entity class 'CNAMTS\\RAVC\\Bundle\\Entity\\Agent'.引用的列名称“id”必须是目标实体类“CNAMTS\\RAVC\\Bundle\\Entity\\Agent”上的主键列。
  • The referenced column name 'id' has to be a primary key column on the target entity class 'CNAMTS\\RAVC\\Bundle\\Entity\\Habilitation'.引用的列名称“id”必须是目标实体类“CNAMTS\\RAVC\\Bundle\\Entity\\Habilitation”上的主键列。

    [Doctrine\\DBAL\\Schema\\SchemaException] The table with name 'valid_comptes.agent_j_habilitation' already exists. [Doctrine\\DBAL\\Schema\\SchemaException] 名称为“valid_comptes.agent_j_habilitation”的表已经存在。

I'm using Symfony 2.8 and Doctrine 2.我正在使用 Symfony 2.8 和 Doctrine 2。

He is my code and BDD definition :他是我的代码和 BDD 定义:

Agent :代理人 :

/**
 * Agent
 *
 * @ORM\Table(name="agent")
 * @ORM\Entity(repositoryClass="...\...\Bundle\Repository\AgentRepository")
 */
class Agent
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(name="age_id", type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="age_numero", type="string", length=5, nullable=true)
     */

    private $ageNumero;

    /**
     * @var string
     *
     * @ORM\Column(name="age_nom", type="string", length=100, nullable=true)
     */

    private $ageNom;

    /**
     * @var string
     *
     * @ORM\Column(name="age_prenom", type="string", length=100, nullable=true)
     */
    private $agePrenom;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Habilitation", inversedBy="agents")
     * @ORM\JoinTable(
     *     name="agent_j_habilitation",
     *     joinColumns={@ORM\JoinColumn(name="fk_hab_id", referencedColumnName="id", nullable=false)},
     *     inverseJoinColumns={@ORM\JoinColumn(name="fk_age_id", referencedColumnName="id", nullable=false)}
     * )
     *
     */
    private $habilitations;

    /**
     * Agent constructor.
     */
    public function __construct()
    {
        $this->habilitations = new ArrayCollection();
    }

    /**
     * @param Habilitation $habilitation
     */
    public function addHabilitation(Habilitation $habilitation)
    {
        $habilitation->addAgent($this);
        $this->habilitations[] = $habilitation;
    }
}

Habilitation :适应能力:

/**
 * Habilitation
 *
 * @ORM\Table(name="habilitation")
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="...\...\Bundle\Repository\HabilitationRepository")
 */
class Habilitation
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(name="hab_id", type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="hab_libelle", type="string", length=50, nullable=true)
     */
    private $habLibelle;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Agent", mappedBy="habilitations")
     */
    private $agents;

    /**
     * Habilitation constructor.
     */
    public function __construct()
    {
        $this->agents = new ArrayCollection();
    }

    /**
     * @param Agent $agent
     */
    public function addAgent(Agent $agent)
    {
        $this->agents[] = $agent;
    }
}

AjoutUserType : AjoutUserType :

class AjoutUserType extends AbstractType
{    
    /**
     * Constructor.
     *
     */
    public function __construct()
    {
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('ageNumero', 'text', [
                'label' => 'Numéro'
            ])
            ->add('ageNom', 'text', [
                'label' => 'Nom'
            ])
            ->add('agePrenom', 'text', [
                'label' => 'Prénom'
            ])
            ->add('habilitations', EntityType::class, [
                'class' => 'RAVCBundle:Habilitation',
                'label' => 'Habilitation',
                'property' => 'habLibelle',
                'multiple' => true,
                'placeholder' => '-- Sélectionnez une habilitation --',
            ]);
    }



    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            [
                'data_class' => Agent::class
            ]
        );
    }
}

Action Controller :动作控制器:

   /**
     * @Route("/ajoutUser", name="ravc_ajoutUser")
     * @Method({"GET", "POST"})
     * @internal param Request $request
     */
    public function newAgentAction(Request $request)
    {
        $agent = new Agent();

        $form = $this->createForm(new AjoutUserType(), $agent);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($agent);
            $em->flush();
            $this->notification('L\'agent a été ajouté avec succès.');

            return $this->redirectToRoute('ravc_ajoutUser');
        }

        return $this->render('RAVCBundle:Admin:ajoutUser.html.twig', ['form' => $form->createView()]);
    }

Table definition :表定义:

CREATE TABLE `agent` (
  `age_id` int(11) NOT NULL AUTO_INCREMENT,
  `age_numero` varchar(6) DEFAULT NULL,
  `age_nom` varchar(100) DEFAULT NULL,
  `age_prenom` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`age_id`)
) ENGINE=InnoDB AUTO_INCREMENT=91 DEFAULT CHARSET=latin1;

CREATE TABLE `agent_j_habilitation` (
  `ajh_id` int(11) NOT NULL AUTO_INCREMENT,
  `fk_hab_id` int(11) NOT NULL,
  `fk_age_id` int(11) NOT NULL,
  PRIMARY KEY (`ajh_id`),
  KEY `ajh_fk_hab_id` (`fk_hab_id`),
  KEY `ajh_fk_age_id` (`fk_age_id`),
  CONSTRAINT `ajh_fk_age_id` FOREIGN KEY (`fk_age_id`) REFERENCES `agent` (`age_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `ajh_fk_hab_id` FOREIGN KEY (`fk_hab_id`) REFERENCES `habilitation` (`hab_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Table structure for habilitation
-- ----------------------------
DROP TABLE IF EXISTS `habilitation`;
CREATE TABLE `habilitation` (
  `hab_id` int(11) NOT NULL AUTO_INCREMENT,
  `hab_libelle` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`hab_id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=latin1;

The doctrine annotation should reflect the real column name (as suggested of the schema validate) and for first ( joinColumn ) you should define the start entity data), so try this:原则注释应该反映真实的列名(如模式验证所建议的那样),首先( joinColumn )你应该定义起始实体数据),所以试试这个:

/**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="Habilitation", inversedBy="agents")
 * @ORM\JoinTable(
 *     name="agent_j_habilitation",
 *     joinColumns={@ORM\JoinColumn(name="fk_age_id", referencedColumnName="age_id", nullable=false)},
 *     inverseJoinColumns={@ORM\JoinColumn(name="fk_hab_id", referencedColumnName="hab_id", nullable=false)}
 * )
 *
 */
private $habilitations;

This should fix the doctrine:schema:validate command这应该修复了doctrine:schema:validate命令

In the AjoutUserType the relation should be mapped by a CollectionType instead of an EntityTypeAjoutUserType 中,关系应该由CollectionType而不是EntityType映射

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM