Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2 Doctrine2可选一对一关系出现问题_Symfony_Orm_Doctrine Orm_One To One - Fatal编程技术网

Symfony2 Doctrine2可选一对一关系出现问题

Symfony2 Doctrine2可选一对一关系出现问题,symfony,orm,doctrine-orm,one-to-one,Symfony,Orm,Doctrine Orm,One To One,我对Symfony2中的Doctrine2和两个相关实体有问题 有一个用户实体可以(不必)引用一个包含传记等信息的usermeta实体 usermeta是可选的,因为用户是由另一个系统导入的,而usermeta是在我的应用程序中管理的 当然,我想同时保存两者,因此保存用户必须创建或更新usermeta实体 两者都由一个名为aduserid的列(两个表中的名称相同)连接 我已经认识到,如果usermeta是一个可选的引用,那么在这种情况下,拥有方应该是usermeta,否则条令会加载用户并需要us

我对Symfony2中的Doctrine2和两个相关实体有问题

有一个用户实体可以(不必)引用一个包含传记等信息的usermeta实体

usermeta是可选的,因为用户是由另一个系统导入的,而usermeta是在我的应用程序中管理的

当然,我想同时保存两者,因此保存用户必须创建或更新usermeta实体

两者都由一个名为aduserid的列(两个表中的名称相同)连接

我已经认识到,如果usermeta是一个可选的引用,那么在这种情况下,拥有方应该是usermeta,否则条令会加载用户并需要usermeta实体——但它并不总是存在

请注意User->setMeta.中的注释

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity
 */
class User
{
/**
 * @var Usermeta
 * @ORM\OneToOne(targetEntity="Usermeta", mappedBy="user", cascade={"persist"})
 */
protected $meta;

public function getMeta()
{
    return $this->meta;
}

/**
 * 
 * @param Usermeta $metaValue 
 */
public function setMeta($metaValue)
{        
// I've tried setting the join-column-value here 
//  - but it's not getting persisted
// $metaValue->setAduserid($this->getAduserid());

// Then I've tried to set the user-object in Usermeta - but then 
//  it seems like Doctrine wants to update Usermeta and searches
//  for ValId names aduserid (in BasicEntityPersister->_prepareUpdateData) 
//  but only id is given -  so not luck here
// $metaValue->setUser($this);           

    $this->meta = $metaValue;
}

/**
 * @var integer
 *
 * @ORM\Column(name="rowid", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;


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

/**
 * @var integer
 *
 * @ORM\Column(name="ADuserid", type="integer", nullable=false)
 */
private $aduserid;

/**
 * Set aduserid
 *
 * @param integer $aduserid
 * @return User
 */
public function setAduserid($aduserid)
{
    $this->aduserid = $aduserid;

    return $this;
}

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

// some mor fields.... 
}
以及Usermeta类:

/**
 * Usermeta
 *
 * @ORM\Table(name="userMeta")
 * @ORM\Entity
 */
class Usermeta
{
/**
 * @ORM\OneToOne(targetEntity="User", inversedBy="meta")
 * @ORM\JoinColumn(name="ADuserid", referencedColumnName="ADuserid")
 */
protected $user;

public function getUser()
{
    return $this->$user;
}    

public function setUser($userObj)
{
    $this->user = $userObj;
}

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @var integer
 *
 * @ORM\Column(name="ADuserid", type="integer", nullable=false)
 */
private $aduserid;

/**
 * Set aduserid
 *
 * @param integer $aduserid
 * @return User
 */
public function setAduserid($aduserid)
{
    $this->aduserid = $aduserid;

    return $this;
}

/**
 * Get aduserid
 *
 * @return integer 
 */
public function getAduserid()
{
    return $this->aduserid;
}
}
控制器代码如下所示:

...

$userForm->bind($request);

    if($userForm->isValid()) {
        $em->persist($user);
        $em->flush();
    }
...

你用了错误的关系来解决你的问题

您需要的是从UsermetaUser

双向一对一关系意味着:

  • 用户必须具有Usermeta对象
  • Usermeta对象必须有一个用户
  • 在你的情况下,你只需要第二个条件

    这意味着您只能从Usermeta中删除用户,而不能反过来


    不幸的是,理论关系。

    阅读我自己的老问题非常有趣,因为我现在第一眼就看到了这个问题

    当谈到解决方案时,我认为条令只能处理名为“id”的id,但是。。。aduserid只是没有标记为ID,它缺少ID注释,并且无法使用join列的字段


    第二件事,Zdenek Machek是对的:它必须被标记为可为null。

    我得到了错误消息“spl\u object\u hash()期望参数1为object,null在…”中给出。。我试图定义一个双向
    一对一
    关系,而反向值可能是
    null
    。这给出了错误消息。去掉关系的反面解决了问题。
    很遗憾,
    不支持零或一对一的关系。

    我希望我不会因为提交这个很晚的答案而打扰任何人,但我是如何解决这个问题的:

    /**
     * @var Takeabyte\GripBundle\Entity\PDF
     * @ORM\OneToOne(targetEntity="Takeabyte\GripBundle\Entity\PDF", inversedBy="element", fetch="EAGER", orphanRemoval=true)
     */
    protected $pdf = null;
    
    我添加了
    =null添加到属性声明中。我希望这对任何读到这篇文章的人都有帮助。

    Zdenek Machek的评论几乎是正确的。从Doctrine2文档中可以看到,nullable选项应该在连接注释(@JoinColumn)中,而不是在映射注释(@OneToOne)中

    @JoinColumn文档:

    此注释用于@ManyToOne、@OneToOne字段中的关系上下文以及嵌套在@ManyToMany中的@JoinTable上下文中。此注释不是必需的。如果未指定属性名称,则从表和主键名称推断属性名称和referencedColumnName

    所需属性:

    名称:保存此关系的外键标识符的列名。在@JoinTable的上下文中,它指定联接表中的列名

    referencedColumnName:用于连接此关系的主键标识符的名称

    可选属性:

    unique:确定此关系是否在受影响的实体之间是独占的,并且应在数据库约束级别强制执行。默认为false

    nullable:确定是否需要相关实体,或者null是否是关系的允许状态。默认为true。

    onDelete:级联操作(数据库级)

    onUpdate:级联操作(数据库级)

    columnDefinition:在列名之后开始并指定完整(不可移植!)列定义的DDL SQL代码段。此属性允许使用高级RMDBS特性。如果需要稍微不同的列定义来连接列,例如关于NULL/NOTNULL默认值,则有必要在@JoinColumn上使用此属性。但是默认情况下,@Column上的“columnDefinition”属性也会设置相关的@JoinColumn的columnDefinition。这是使外键工作所必需的

    @OneToOne文档:

    @OneToOne注释的工作原理几乎与@ManyToOne完全相同,还可以指定一个附加选项。使用目标实体表和主键列名的@JoinColumn的默认配置也适用于此处

    所需属性:

    targetEntity:引用的目标实体的FQCN。如果两个类位于同一命名空间中,则可以是非限定类名。重要提示:无前导反斜杠

    可选属性:

    级联:级联选项

    抓取:懒惰或渴望的人

    孤立删除:布尔值,用于指定是否应按原则删除孤立的、未连接到任何拥有实例的反向OneToOne实体。默认为false

    反向方:反向方属性指定实体中作为关系反向方的字段


    设置meta-nullable=true/***@var Usermeta*@ORM\OneToOne(targetEntity=“Usermeta”,mappedBy=“user”,cascade={“persist”},nullable=true)*/protected$meta@Zdenek,OneToOne注释没有可为空的参数。它是
    @JoinColumn
    的参数。任何类字段的默认值都为空。