üzerinde yabancı varlık istisnası üzerinden User
ve UserProfile
OneToOne ile ilgili Doctrine ORM varlıkları var. Her zaman bir çift olarak var olmalı, UserProfile
olmadan User
olmalıdır.Doctrine OneToOne kimliği
UserProfile kullanıcının kimliğine sahipken, kullanıcının kimliğini autoincrement'ten alması gerekir. Yani her ikisi de aynı kimliğe sahip olmalı ve ilişkiyi kurmak için başka bir sütun yoktur (Doctrine docs: Identity through foreign Entities).
UserProfile'ın kimliği, aynı anda hem birincil anahtar (PK) hem de yabancı anahtar (FK) 'dir.
Ayarlamayı başardım, ancak önce Kullanıcı'nın kaydedilmesini ve daha sonra UserProfile oluşturulmasını ve ayrı bir adımda kaydedilmesini gerektirir.
İstediğim UserProfile hep yapıcı içinde, Kullanıcı ile oluşturulduğunu, ancak bunu yaparsanız, bu durum almak:
Doctrine\ORM\ORMInvalidArgumentException: The given entity of type 'AppBundle\Entity\UserProfile' (AppBundle\Entity\[email protected]) has no identity/no id values set. It cannot be added to the identity map.
kod aşağıda görebilirsiniz - çalıştığını, ancak istediğim gibi. Php yorumları ne elde etmek istediğimi gösterir.
Test.php
:
/**
* It works, both saving and loading.
* BUT, it requires that I create and save UserProfile
* in a separate step than saving User step.
*/
// create and save User
$user = new User();
$objectManager->persist($user);
$objectManager->flush();
// create and save UserProfile (this should be unnecessary)
$user->createProfile()
$objectManager->flush();
User.php
:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
* @ORM\Table(name="users")
*/
class User
{
/**
* @var int
*
* @ORM\Column(name="uid", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* It's NULL at first, I create it later (after saving User).
*
* @var UserProfile|null
*
* @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade="persist")
*/
private $profile = null;
public function __construct()
{
// I want to create UserProfile inside User's constructor,
// so that it is always present (never NULL):
//$this->profile = new UserProfile($this);
// but this would give me error:
//
// Doctrine\ORM\ORMInvalidArgumentException:
// The given entity of type 'AppBundle\Entity\UserProfile'
// (AppBundle\Entity\[email protected])
// has no identity/no id values set. It cannot be added to the identity map.
}
public function createProfile()
{
$this->profile = new UserProfile($this);
}
}
UserProfile.php
:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="profiles")
*/
class UserProfile
{
/**
* – UserProfile's "uid" column points to User's "uid" column
* – it is PK (primary key)
* - it is FK (foreign key) as well
* – "owning side"
*
* @var User
*
* @ORM\Id
* @ORM\OneToOne(targetEntity="User", inversedBy="profile")
* @ORM\JoinColumn(name="uid", referencedColumnName="uid", nullable=false)
*/
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
test uygulaması: https://github.com/MacDada/DoctrineOneToOneTest
Id bir veritabanı nesnesidir ve modelinizde bir endişe olmamalıdır. Aynı birincil anahtar değere ihtiyaçları olduğu fikrinden vazgeç. Ya da başarısız olursa, birinin otomatik olması ve diğerinin olmaması gerektiği fikrini ortaya çıkar. – Cerad
@Cerad Eski bir uygulama üzerinde yapıyorum - veritabanı nedir. Şu anki şemaya Doktrini ayarlamalıyım, tersi değil… Artı, yukarıdaki kod çalışır. Doktrin, birincil anahtarlar olan yabancı anahtarları işleyebilir. Sadece bir sifondaki varlıkları devam ettiremez. Ya da en azından cevabı arıyorum, doktrini nasıl yapılandırabilsin diye. – MacDada
Yeterince adil. Eğer bir arama yaparsanız, aynı sorunun birkaç yüz varyasyonunu bulacaksınız. Hepsi aynı cevapla. – Cerad