Reputation: 2895
Entities :
Entity Miejsce
class Miejsce
{
/**
*
* @var Lokalizacja $lokalizacja
* @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja",cascade={"persist"})
* @ORM\JoinColumn(name="id", referencedColumnName="miejsce_id")
*/
protected $lokalizacja;
Entity Lokalizacja
class Lokalizacja {
/**
* Lokalizacja.id = Miejsce.id
* @ORM\Column(type="integer")
* @ORM\Id
*/
protected $id;
/**
* @var Miejsce
* @ORM\OneToOne(targetEntity="Miejsce\ObiektyBundle\Entity\Miejsce", inversedBy="lokalizacja")
* @ORM\JoinColumn(name="miejsce_id", referencedColumnName="id")
*/
protected $miejsce;
/**
* @ORM\Column(type="integer")
*/
protected $miejsce_id;
i Create new Miejsce
$miejsce = new Miejsce();
.... $em->persist($miejsce); $em->flush();
and get
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`symfony2_KPB_lazy`.`mMiejsce`, CONSTRAINT `FK_41DB4C8BF396750` FOREIGN KEY (`id`) REFERENCES `mLokalizacja` (`miejsce_id`))
if i first setup lokalizacja
$lokalizacja = new Lokalizacja();
$lokalizacja->setLat($a['lat']);
$lokalizacja->setLng($a['lng']);
$em->persist($lokalizacja);
$em->flush();
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'miejsce_id' cannot be null
if i add persist
/**
*
* @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja",cascade={"persist"})
* @ORM\JoinColumn(name="id", referencedColumnName="miejsce_id")
*/
protected $lokalizacja;
An exception occurred while executing 'INSERT INTO mLokalizacja (miejsce_id, lat, lng, zoom, textAdres, mMiejscowosci_id, mPowiaty_id, mWojewodztwa_id, street) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' with params [null, 49.658192, 18.825332, null, null, null, null, null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'miejsce_id' cannot be null
when run code
$miejsce = new Miejsce();
$lokalizacja = new Lokalizacja();
$lokalizacja->setLat($a['lat']);
$lokalizacja->setLng($a['lng']);
$lokalizacja->setMiejsce($miejsce);
$miejsce->setLokalizacja($lokalizacja);
$em->persist($miejsce);
$em->flush();
when i try add miejsce in phpMyAdmin - i get
symfony2_KPB
.mMiejsce
, CONSTRAINT FK_41DB4C8BF396750
FOREIGN KEY (id
) REFERENCES mLokalizacja
(miejsce_id
))So how to add Miejsce ?
UPDATE1
class Miejsce
{
/**
* @var Lokalizacja $lokalizacja
* @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja")
*/
protected $lokalizacja;
/**
* @ORM\Entity
*
* @ORM\Table(name="mLokalizacja", indexes={
@ORM\Index(name="index_latLng", columns={"lat","lng"})
})
*
*/
class Lokalizacja {
/**
* @var Miejsce
* @ORM\OneToOne(targetEntity="Miejsce\ObiektyBundle\Entity\Miejsce", inversedBy="lokalizacja")
* @ORM\JoinColumn(name="miejsce_id", referencedColumnName="id")
*/
protected $miejsce;
i update database and see (this is phpmyadmin table structure):
CREATE TABLE IF NOT EXISTS `mMiejsce` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nazwa` varchar(255) COLLATE utf8_polish_ci NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`lokalizacja_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
and lokalizacja
CREATE TABLE IF NOT EXISTS `mLokalizacja` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lat` double NOT NULL,
`lng` double NOT NULL,
`zoom` int(11) NOT NULL,
`miejsce_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_4FC27791464204DC` (`miejsce_id`),
Why doctrine add lokalizacja_id to mMiejsce ? And still save is not possible
UPDATE2 i add mappedBy="miejsce", database look ok now but when i try save
class Miejsce
{
/**
* @var Lokalizacja $lokalizacja
* @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja" , mappedBy="miejsce")
*/
protected $lokalizacja;
have error :
A new entity was found through the relationship 'Miejsce\ObiektyBundle\Entity\Miejsce#lokalizacja' that was not configured to cascade persist operations for entity: Miejsce\LokalizacjaBundle\Entity\Lokalizacja@000000006200f93900007f919f6a5a6f. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Miejsce\LokalizacjaBundle\Entity\Lokalizacja#__toString()' to get a clue.
so i add ,cascade={"persist"}
* @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja" , mappedBy="miejsce" ,cascade={"persist"})
now entity save succes but :) i cant delete it - when i try delete miejsce -
i found onDelete="CASCADE" - but have error :
Creation Error] The annotation @ORM\OneToOne declared on property Miejsce\ObiektyBundle\Entity\Miejsce::$lokalizacja does not have a property named "onDelete". Available properties: targetEntity, mapped
By, inversedBy, cascade, fetch, orphanRemoval
when add to * @ORM\OneToOne(targetEntity="Miejsce\LokalizacjaBundle\Entity\Lokalizacja" , mappedBy="miejsce" ,cascade={"persist"})
So where add cascade delete ?
UPDATE3
ok when i add
* @ORM\JoinColumn(name="miejsce_id", referencedColumnName="id", onDelete="CASCADE")
to lokalizacja everythink work.
Upvotes: 0
Views: 1170
Reputation: 23068
You are trying to establish a oneToOne bidirectional relationship. Such a relationship (as all bidirectional ones) needs the mention inversedBy
on one side and mappedBy
on the other, which you forgot in your annotation.
For more detailed informations about relationships, see Doctrine documentation.
But regarding your particular need, you can start with the following.
Miejsce:
class Miejsce
{
/**
* @OneToOne(targetEntity="Lokalizacja", mappedBy="miejsce", cascade={"remove"})
*/
private $lokalizacja;
Here is where you forgot mappedBy
.
Lokalizacja:
class Lokalizacja
{
/**
* @OneToOne(targetEntity="Miejsce", inversedBy="lokalizacja")
*/
private $miejsce;
When you join based on the id
, JoinColumn is optional and you can omit it (as I did).
Then, you go on normally with:
// (...)
$em->persist($miejsce);
$em->flush();
Upvotes: 1