所有しているサブオブジェクトを保持してオブジェクトを作成するのに問題があります。具体的には、少なくとも 1 つの PGPKey オブジェクトを所有する User クラスがあります。
次のコード スニペットは失敗します。
$user = new User("username","password");
$em->persist($user);
エラーで:
SQLSTATE [23000]: 整合性制約違反: 1048 列 'PGPKeys.owner' を null にすることはできません
私にとっての問題は次のとおりです。 PGPKey.owner に対応する User.idUser フィールドは GeneratedValue であるため、persist が呼び出された時点ではまだ定義されていません。次に、Doctrine は最初に PGPKey を保存しようとしますが、SQL は所有者が null であることを許可しません。ユーザーが最初に保存される場合、生成された ID を使用して PGPkey の所有者フィールドに保存できます。
Doctrine が所有オブジェクトの前に所有オブジェクトを保存することを期待していましたが、そうではないか、何かが欠けているようです。
User.postPersist() は実行されません。
ユーザー.php
/**
* @HasLifecycleCallbacks
* @Entity
*/
class user {
/**
* @Id
* @Column(type="integer", nullable=false, columnDefinition="int(11) unsigned NOT NULL AUTO_INCREMENT");
* @GeneratedValue(strategy="AUTO")
*/
protected $idUser;
/**
* @Column(type="string", nullable=false, columnDefinition="VARCHAR( 255 ) NOT NULL")
*/
protected $username;
/**
* @OneToMany(targetEntity="PGPKey", mappedBy="owner", cascade={"persist","remove"}, orphanRemoval=true)
* @var PGPKey[]
*/
protected $PGPKeys;
public function __construct($username,$password)
{
$this->PGPKeys = new ArrayCollection();
$this->username = $username;
$this->setPassword($password);
}
/** @PostPersist */
public function postPersist(){
foreach ($this->PGPKeys as $key)
{
$key->setOwner($this->getId());
}
}
public function setPassword($newPassword, $oldPassword = false)
{
if ($oldPassword === false || !count($this->PGPKeys))
{
$newkey = new PGPKey($newPassword);
$newkey->setOwner($this->idUser);
$this->PGPKeys[] = $newkey;
}
else
{
$this->PGPKeys[count($this->PGPKeys) - 1]->changePassword($oldPassword, $newPassword);
}
}
}
PGPKey.php
/**
* @Entity
*/
class PGPKey
{
/**
* @Id
* @Column(type="integer", unique=true, columnDefinition="int(11) unsigned NOT NULL AUTO_INCREMENT");
* @GeneratedValue(strategy="AUTO")
*/
protected $idKey;
/**
* @Column(type="integer", columnDefinition="int(11) unsigned NOT NULL");
* @ManyToOne(targetEntity="User", inversedBy="PGPKeys");
*/
protected $owner;
public function __construct($password)
{
//do RSA stuff
}
public function setOwner($ownerid)
{
$this->owner = $ownerid;
return $this;
}
}