简体   繁体   English

教义2和垂直分区

[英]Doctrine 2 and vertical partitioning

I'm currently working on a project for which i have to deal with a lot of users fields (+/- 80). 我目前正在从事一个项目,我必须处理很多用户字段(+/- 80)。 My first approach was (and still is) to vertically partition the user table in 4 tables : main informations, administrative informations, banking informations, statistics informations. 我的第一种方法是(现在仍然是)将用户表垂直划分为4个表:主要信息,管理信息,银行信息,统计信息。 The ids of the 3 extra tables rows refer to the auto incremented id of the main table. 3个额外表行的ID是指主表的自动递增ID。

My questions are : 我的问题是:

  1. Is it relevant to do so ? 这样做相关吗?
  2. It seems like, with the way i did the association, Doctrine isn't able to flush one object into database in one shot : 用我进行关联的方式,Doctrine似乎无法一口气将一个对象刷新到数据库中:

Entity of type MyVendor\\User\\UserBundle\\Entity\\UsersInfosBank is missing an assigned ID for field 'id_user'. 类型为MyVendor \\ User \\ UserBundle \\ Entity \\ UsersInfosBank的实体缺少为字段“ id_user”分配的ID。 The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. 该实体的标识符生成策略要求在调用EntityManager#persist()之前填充ID字段。 If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly. 如果要自动生成的标识符,则需要相应地调整元数据映射。

The project will be pushed into production in 3 weeks, so we're still able to go back to a more traditionnal way to store these datas into one huge table… 该项目将在3周内投入生产,因此我们仍然可以采用一种更传统的方式将这些数据存储到一张大表中……

****************UPDATE***************** ****************更新*****************

WHOLE CODE LOGIC BELOW***************** 整个代码逻辑如下*****************


I just removed most of the properties and methods which are not concerned by my problem… 我只是删除了与我的问题无关的大多数属性和方法...

And yes, i'm using FOSUserBundle ;) 是的,我正在使用FOSUserBundle;)

UsersMain Users主要

<?php

namespace LCP\User\UserBundle\Entity;

use FOS\UserBundle\Model\GroupableInterface;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * UsersMain
 *
 * @ORM\Table(name="lcp_users_main")
 * @ORM\Entity
 */
class UsersMain extends BaseUser 
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;


    /**
     *
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersInfosBank", mappedBy="id_user", cascade={"persist"})
     */
    private $infosBank;

    /**
     *
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersApodis", mappedBy="id_user", cascade={"persist"})
     */
    private $apodis;

    /**
     *
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersInfosAdmin", mappedBy="id_user", cascade={"persist"})
     */
    private $infosAdmin;

    /**
     *
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersInfosStats", mappedBy="id_user", cascade={"persist"})
     */
    private $infosStats;



    /**
     * Constructor
     */
    public function __construct()
    {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
        $this->creationDate = new \Datetime();
    }

    /**
     * Set apodis
     *
     * @param \LCP\User\UserBundle\Entity\UsersApodis $apodis
     * @return UsersMain
     */
    public function setApodis(\LCP\User\UserBundle\Entity\UsersApodis $apodis = null)
    {
        if(is_null($this->apodis) && is_null($apodis)){
            $this->apodis = new \LCP\User\UserBundle\Entity\UsersApodis();
        } else {
            $this->apodis = $infosBank;
        }

        $this->apodis->setIdUser($this);

        return $this;
    }

    /**
     * Get apodis
     *
     * @return \LCP\User\UserBundle\Entity\UsersApodis 
     */
    public function getApodis()
    {
        if(is_null($this->infosAdmin)){
            $this->infosAdmin = new \LCP\User\UserBundle\Entity\UsersApodis();
        }
        return $this->apodis;
    }

    /**
     * Set infosAdmin
     *
     * @param \LCP\User\UserBundle\Entity\UsersInfosAdmin $infosAdmin
     * @return UsersMain
     */
    public function setInfosAdmin(\LCP\User\UserBundle\Entity\UsersInfosAdmin $infosAdmin = null)
    {
        if(is_null($this->infosAdmin) && is_null($infosAdmin)){
            $this->infosAdmin = new \LCP\User\UserBundle\Entity\UsersInfosAdmin();
        } else {
            $this->infosAdmin = $infosAdmin;
        }

        $this->infosAdmin->setIdUser($this);

        return $this;
    }

    /**
     * Get infosAdmin
     *
     * @return \LCP\User\UserBundle\Entity\UsersInfosAdmin 
     */
    public function getInfosAdmin()
    {
        if(is_null($this->infosAdmin)){
            $this->infosAdmin = new \LCP\User\UserBundle\Entity\UsersInfosAdmin();
        }
        return $this->infosAdmin;
    }

    /**
     * Set infosStats
     *
     * @param \LCP\User\UserBundle\Entity\UsersInfosStats $infosStats
     * @return UsersMain
     */
    public function setInfosStats(\LCP\User\UserBundle\Entity\UsersInfosStats $infosStats = null)
    {
        if(is_null($this->infosStats) && is_null($infosStats)){
            $this->infosStats = new \LCP\User\UserBundle\Entity\UsersInfosStats();
        } else {
            $this->infosStats = $infosAdmin;
        }

        $this->infosStats->setIdUser($this);

        return $this;
    }

    /**
     * Get infosStats
     *
     * @return \LCP\User\UserBundle\Entity\UsersInfosStats 
     */
    public function getInfosStats()
    {
        if(is_null($this->infosStats)){
            $this->infosStats = new \LCP\User\UserBundle\Entity\UsersInfosStats();
        }
        return $this->infosStats;
    }



}

UsersInfosAdmin UsersInfosAdmin

<?php

namespace LCP\User\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * UsersInfosAdmin
 *
 * @ORM\Table(name="lcp_users_infos_admin", indexes={@ORM\Index(name="pharmacyCip_idx", columns={"pharmacy_cip"})})
 * @ORM\Entity
 */
class UsersInfosAdmin
{

    /**
     * @var integer
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersMain", cascade={"persist"}, inversedBy="infosAdmin")
     */
    private $id_user;


    /**
     * Set id_user
     *
     * @param \LCP\User\UserBundle\Entity\UsersMain $idUser
     * @return UsersInfosAdmin
     */
    public function setIdUser(\LCP\User\UserBundle\Entity\UsersMain $idUser)
    {
        $this->id_user = $idUser;

        return $this;
    }

    /**
     * Get id_user
     *
     * @return \LCP\User\UserBundle\Entity\UsersMain 
     */
    public function getIdUser()
    {
        return $this->id_user;
    }
}

UsersInfosStats UsersInfosStats

<?php

namespace LCP\User\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * UsersInfosStats
 *
 * @ORM\Table(name="lcp_users_infos_stats")
 * @ORM\Entity
 */
class UsersInfosStats
{
    /**
     * @var integer
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="LCP\User\UserBundle\Entity\UsersMain", cascade={"persist"}, inversedBy="infosStats")
     */
    private $id_user;

    /**
     * Set id_user
     *
     * @param \LCP\User\UserBundle\Entity\UsersMain $idUser
     * @return UsersInfosStats
     */
    public function setIdUser(\LCP\User\UserBundle\Entity\UsersMain $idUser)
    {
        $this->id_user = $idUser;

        return $this;
    }

    /**
     * Get id_user
     *
     * @return \LCP\User\UserBundle\Entity\UsersMain 
     */
    public function getIdUser()
    {
        return $this->id_user;
    }
}

Here is how i create a user (it is through a secured admin area form) : 这是我创建用户的方式(通过安全的管理区域表单):

/**
* This action get the field from the form
*/
public function userSaveAction(Request $request)
{
    $userManager = $this->get('fos_user.user_manager');
    $this->request = $request;
    $userValues = $this->getRequest()->request->all();
    $this->em = $this->getDoctrine()->getManager();

    $user = $this->processUser($userValues);

    $userManager->updateUser($user, false);

    return $this->redirect($this->generateUrl('lcp_admin_user_edit', ['id'=>$user->getId()]));
}

/**
* This method process user fields and uses setters (or getters for joined entities) to set datas of user
*/
private function processUser($userValues)
{
    if($userValues['userId']=="") {
        $user = $this->get('fos_user.user_manager')->createUser();
    } else {
        $user = $this->em->getRepository('LCPUserBundle:UsersMain')
                ->findOneBy(['id' => $userId]);
    }

    //construction of related entities
    $user->setInfosAdmin();
    $user->setInfosBank();
    $user->setInfosStats();
    $user->setApodis();

    unset($userValues['userId']);

    //this method inspect submitted field to check if they are mandatory or if current user is allowed to modify them
    $this->fields = $this->getInfosFields();

    foreach($userValues as $input=>$value){
        list($entity,$input)=explode('-',$input);
        if($input=='plainPassword' && $value==''){
            continue;
        }
        if($entity=='Main'){
            $setter = 'set'.ucfirst($input);
            $user->$setter($value);
        } else {
            $setter = 'set'.ucfirst($input);
            $join = 'get'.$entity;

            $user->$join()->$setter($value);
        }
    }
    return $user;
}

According to the comments your UsersMain property need to be like this: 根据评论,您的UsersMain属性必须像这样:

/**
 * Join administrative informations
 * @ORM\OneToOne(targetEntity="MyVendor\User\UserBundle\Entity\UsersInfosAdmin", mappedBy="userMain", cascade={"persist"}, orphanRemoval=true)
 */
private $infosAdmin;

/**
 * Setter InfosAdmin
 */
public function setInfosAdmin(UsersInfosAdmin $infosAdmin)
{
    $this->infosAdmin = $infosAdmin;
    $this->infosAdmin->setUserMain($this); <--- add this to set userMain on associated object

    return $this;
}

then your UsersInfosAdmin properties need to be like this: 那么您的UsersInfosAdmin属性需要像这样:

/**
 * @var integer
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
 private $id;

/**
 * @ORM\OneToOne(targetEntity="MyVendor\User\UserBundle\Entity\UsersMain", inversedBy="userMain")
 */
 private $userMain;

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

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