У меня проблема с составным первичным ключом в отношении OneToOne в Доктрине. Когда один объект не имеет никакого отношения (что обычно возможно) я получил следующее сообщение об ошибке:Doctrine2 oneToOne составной первичный ключ не может быть нулевым
Doctrine\Common\Proxy\Exception\OutOfBoundsException: Missing value for
primary key idEngine on Farkas\CoreBundle\Entity\Engine
Я нашел проблему непосредственно в Учении:
vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php Line 2116
// TODO: Is this even computed right in all cases of composite keys?
foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
$joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
if ($joinColumnValue !== null) {
if ($targetClass->containsForeignIdentifier) {
$associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue;
} else {
$associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
}
}
}
$joinColumnValue
является нулевым, когда внешний ключ пуст, потому что массив $data
, который содержит данные строки, не имеет ключа массива для поля отношения. Комментарий todo говорит мне, что что-то не так с составными ключами?
Вот два моих Entities (только небольшой тест, не думайте о логике моих сущностей ^^):
1-й
/**
* Car
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Farkas\CoreBundle\Entity\CarRepository")
*/
class Car
{
/**
* @var integer
*
* @ORM\Column(name="id_car", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $idCar;
/**
* @var string
*
* @ORM\Column(name="brand", type="string", length=255)
*/
private $brand;
/**
* @var string
*
*
* @ORM\OneToOne(targetEntity="Engine", mappedBy="car")
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="engine", referencedColumnName="id_engine"),
* @ORM\JoinColumn(name="country", referencedColumnName="country")
*)
*/
private $engine;
/**
* @var integer
* @ORM\Id
* @ORM\Column(name="country", type="integer")
*/
private $country;
}
второй
/**
* Engine
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Farkas\CoreBundle\Entity\EngineRepository")
*/
class Engine
{
/**
* @var integer
*
* @ORM\Column(name="id_engine", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $idEngine;
/**
* @var string
*
* @ORM\Column(name="engineName", type="string", length=255)
*/
private $engineName;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* @var integer
* @ORM\Id
* @ORM\Column(name="country", type="integer")
*/
private $country;
/**
* @var integer
*
* @ORM\OneToOne(targetEntity="Car", inversedBy="engine")
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="car_id", referencedColumnName="id_car"),
* @ORM\JoinColumn(name="country", referencedColumnName="country")
*)
*/
private $car;
}
Когда я попробуйте выполнить findAll()
Я получил сообщение об ошибке выше. Когда я выполнять сгенерированный SQL непосредственно в MySQL, все выглядит отлично:
SELECT t0.id_car AS id_car1, t0.brand AS brand2, t0.country AS country3,
t0.engine AS engine4, t0.country AS country5 FROM Car t0
Это означает, что гидратация не может работать с пустым oneToOne отношением.
просто идея, почему бы вам не заставить свой двигатель на вашем автомобиле присоединиться к просто двигателю, а затем включить страны автомобиля и двигателя в новый объект страны. Тогда у вас могут быть нулевые отношения между ними. –
Пример действительно глупый. Вот как это выглядит для моего реального кода @work. –