2017-03-06 37 views
0

主義實體協會我已經配置稱爲用戶和ApiKey兩個實體。他們下面有一對一的關係映射。不工作

用戶:

/** 
* @var integer 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @ORM\Column(name="username", type="string", length=225, unique=true) 
* @Assert\NotBlank(message="Please enter a username.") 
* @Assert\Length(
*  min = 2, 
*  max = 180, 
*  minMessage = "Your username must be at least {{ limit }} characters", 
*  maxMessage = "Your username cannot be longer than {{ limit }} characters" 
*) 
*/ 
protected $username; 

/** 
* @ORM\Column(name="email", type="string", length=225) 
* @Assert\NotBlank(message="Please enter a email.") 
* @Assert\Email(message = "The email '{{ value }}' is not a valid email.") 
*/ 
protected $email; 

/** 
* @ORM\Column(name="salt", type="text") 
*/ 
protected $salt; 

/** 
* @ORM\Column(name="password", type="string", length=225) 
* @Assert\NotBlank(message="Please enter a password.") 
* @Assert\Length(
*  min = 7, 
*  minMessage = "Your password must be at least {{ limit }} characters long." 
*) 
*/ 
protected $password; 

/** 
* @Assert\NotBlank(message="Please enter a confirmation password.") 
*/ 
protected $confirmationPassword; 

/** 
* @ORM\Column(name="roles", type="json_array") 
*/ 
protected $roles; 

/** 
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user") 
* @ORM\JoinColumn(name="id", referencedColumnName="user_id") 
*/ 
protected $apiKey; 

ApiKey:

/** 
* @var integer 
* @ORM\Column(name="user_id", type="integer") 
* @ORM\Id 
*/ 
protected $user_id; 

/** 
* @var string 
* @ORM\Column(name="api_key", unique=true, type="string", length=225) 
* @Assert\NotBlank(message="Please enter a username.") 
*/ 
protected $api_key; 

/** 
* @var string 
* @ORM\Column(name="expires", type="datetime") 
* @Assert\NotBlank(message="Please enter a username.") 
*/ 
protected $expires; 

/** 
* @ORM\OneToOne(targetEntity="User", inversedBy="apiKey") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
protected $user; 

然而,當我運行下面的代碼:

$user = new User(); 
    $user->setUsername($request->get('username')); 
    $user->setSalt(uniqid(mt_rand(), true)); 
    $user->setPassword(hash('sha256', $user->getSalt() . $request->get('password'))); 
    $user->setRoles(['ROLE_API']); 

    $apiKey = new ApiKey(); 
    $apiKey->setUser($user); 

    $this->getDoctrine()->getManager()->persist($user); 
    $this->getDoctrine()->getManager()->flush(); 

我得到這個錯誤,我究竟做錯了什麼?

An exception occurred while executing 'INSERT INTO users (username, email, salt, password, roles, id) VALUES (?, ?, ?, ?, ?, ?)' with params ["bobsmith", "[email protected]", "147423531058bd98d9ac9af4.48409486", "6196012972b1294e7f3fbf9c140bc26f0bf3b354ea37d00753bc1ecba0a72866", "[\"ROLE_API\"]", null]:SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (app . users , CONSTRAINT FK_1483A5E9BF396750 FOREIGN KEY (id) REFERENCES api_key (user_id))

變化:

$user = new User(); 
    $user->setUsername($request->get('username')); 
    $user->setSalt(uniqid(mt_rand(), true)); 
    $user->setPassword(hash('sha256', $user->getSalt() . $request->get('password'))); 
    $user->setRoles(['ROLE_API']); 

    $apiKey = new ApiKey(); 
    $this->getDoctrine()->getManager()->persist($apiKey); 
    $apiKey->setUser($user); 

    $this->getDoctrine()->getManager()->persist($user); 
    $this->getDoctrine()->getManager()->flush(); 

Entity of type AppBundle\Entity\ApiKey is missing an assigned ID for field 'user_id'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

+0

嘗試添加 「$用戶> setApiKey($ apiKey);」 $ apiKey =新ApiKey後(); –

+0

我添加了您的更改^。但是,現在出現此錯誤:的appbundle \實體\ ApiKey @ 000000004adc072f00000000540f2869: 一個新的實體通過中沒有配置級聯堅持操作的實體之間的關係「的appbundle \實體\用戶#apiKey」發現。爲了解決這個問題:無論是顯式調用的EntityManager#堅持()對這個未知的實體或配置級聯堅持這種關聯在例如@ManyToOne映射(..,級聯= {「堅持」})。如果您無法找到哪個實體導致問題實現'AppBundle \ Entity \ ApiKey #__ toString()'以獲取線索。 – Freid001

+0

刷新之前,也加入這一行函數:$ this-> getDoctrine() - > getManager() - >堅持($ apiKey); –

回答

2

這是2倍的評論,WH在西里爾說,但它也因爲你有你的用戶類的額外映射:

/** 
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user") 
* @ORM\JoinColumn(name="id", referencedColumnName="user_id") // Remove this line 
*/ 
protected $apiKey; 

應該僅僅是:

/** 
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user") 
*/ 
protected $apiKey; 

只有實際做的映射關係的映射需要連接列。通過使用mappedBy="user"你告訴學說看ApiKey類user屬性如何映射這種關聯。在這裏有一個連接列是導致問題。

+1

事實上,我至少應該仔細閱讀我複製/粘貼的內容。 要解釋Chausser剛纔所說的內容,當關系的一邊有'mappedBy'字段時,它是關係的*所有者*,並且將創建和管理隱藏的聯接表。 當另一方想要雙向關係時,它會創建一個'JoinColumn'來獲得對所有者連接表的讀取權限。 –

3

你似乎在這裏有一個級聯問題。您正在將用戶保存在數據庫中,但該用戶已鏈接到尚未保存在數據庫中的ApiKey。要告訴它需要堅持它的ApiKey與它一起,你需要添加一個梯級上的用戶和ApiKey

/** 
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user", cascade="persist") 
*/ 
protected $api_key; 

之間依然存在。如果你也想刪除ApiKey隨着用戶就可以使用cascade={"persist", "remove"} 玩家你可以找到所有關於協會here學說文檔

編輯:刪除行// @ORM\JoinColumn(name="id", referencedColumnName="user_id"),不應該對業主方存在,如Chausser

+1

我做了更改,但現在出現此錯誤: AppBundle \ Entity \ ApiKey類型的實體缺少爲字段'user_id'分配的ID。此實體的標識符生成策略要求在調用EntityManager#persist()之前填充ID字段。如果您想要自動生成標識符,則需要相應地調整元數據映射。 – Freid001