Я использую Doctrine 2 ORM, и у меня есть эта проблема.
У меня есть три сущности, Адрес , Местоположение и OrganizationalUnit .
Отношения между ними:
Адрес (OneToOne) Расположение,
OrganizationalUnit (ManyToOne) Адрес.
Проблема:
Когда я пытаюсь сохранить все объекты (код ниже), он устанавливает OrganizationalUnit (FK: Address) в ноль вместо Address (ID).
Когда я выбираю (найду) или обновляю что-то, все работает хорошо.
Код:
Вот код, который делает постоянные.
//Entity manager
$em = Zend_Registry::get('em');
$location = new Application_Model_Location();
$location->setLatitude(0);
$location->setLongitude(0);
$address = new Application_Model_Address();
$address->setCity('test');
$address->setCountry('cz');
$address->setNumber(123456);
$address->setPostalCode(123456);
$address->setStreet('street');
$address->setLocation($location);
$location->setAddress($address);
$organization = new Application_Model_Organizationalunit();
$organization->setName('novytest');
$organization->setType($organizationType[0]);
$address->addOrganization($organization);
$organization->setAddress($address);
$em->persist($location);
$em->persist($address);
$em->persist($organization);
$em->flush();
Этот код генерирует SQL следующим образом (он у меня из журнала MySQL Server)
START TRANSACTION
INSERT INTO Location (longitude, latitude, cartographicSquare, id) VALUES ('0', '0', NULL, NULL)
INSERT INTO Address (street, number, city, postalCode, country, id) VALUES ('ulice', '123456', 'test', '123456', 'cz', 11)
INSERT INTO OrganizationalUnit (name, type, address, parentId) VALUES ('novytest', 7, 0, NULL)
ROLLBACK
Что является неправильным 'couse of' ('novytest', 7, 0, NULL) "этот ноль (модель данных ниже)
Данные выглядят так:
CREATE TABLE `rotifera`.`location` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`longitude` double NOT NULL,
`latitude` double NOT NULL,
`cartographicSquare` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `rotifera`.`address` (
`id` int(11) NOT NULL DEFAULT '0',
`street` varchar(100) NOT NULL,
`number` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`postalCode` varchar(10) NOT NULL,
`country` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_Address_Location` (`id`),
CONSTRAINT `fk_Address_Location` FOREIGN KEY (`id`) REFERENCES `location` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `rotifera`.`organizationalunit` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`type` int(11) NOT NULL,
`address` int(11) DEFAULT NULL,
`parentId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_OrganizationalUnit_Address1` (`address`),
KEY `fk_OrganizationalUnit_OrganizationalUnitType1` (`type`),
KEY `fk_OrganizationalUnit_OrganizationalUnit1` (`parentId`),
CONSTRAINT `fk_OrganizationalUnit_Address1` FOREIGN KEY (`address`) REFERENCES `address` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_OrganizationalUnit_OrganizationalUnit1` FOREIGN KEY (`parentId`) REFERENCES `organizationalunit` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_OrganizationalUnit_OrganizationalUnitType1` FOREIGN KEY (`type`) REFERENCES `organizationalunittype` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Мои модели ORM выглядят так
Для местоположения:
/**
* @Entity
* @table(name="Location")
*/
class Application_Model_Location {
/**
* @id @column(type="integer")
* @generatedValue
*/
private $id;
/** @column(type="float") */
private $longitude;
/** @column(type="float") */
private $latitude;
/** @column(type="integer", nullable=true) */
private $cartographicSquare;
/**
* @OneToOne(targetEntity="Application_Model_Address", mappedBy="location")
*/
private $address;
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function getLongitude() {
return $this->longitude;
}
public function setLongitude($longitude) {
$this->longitude = $longitude;
}
public function getLatitude() {
return $this->latitude;
}
public function setLatitude($latitude) {
$this->latitude = $latitude;
}
public function getCartographicSquare() {
return $this->cartographicSquare;
}
public function setCartographicSquare($cartographicSquare) {
$this->cartographicSquare = $cartographicSquare;
}
public function getAddress() {
return $this->address;
}
public function setAddress($address) {
$this->address = $address;
}
Для адреса:
/**
* @Entity
* @table(name="Address")
*/
class Application_Model_Address {
/**
* @id
* @column(type="integer")
* @generatedValue
*/
private $id;
/** @column(length=100) */
private $street;
/** @column(length=100) */
private $number;
/** @column(length=100) */
private $city;
/** @column(length=100) */
private $postalCode;
/** @column(length=100) */
private $country;
/**
* @OneToOne(targetEntity="Application_Model_Location", inversedBy="address")
* @JoinColumn(name="id", referencedColumnName="id")
*/
private $location;
/**
* @OneToMany(targetEntity="Application_Model_Organizationalunit", mappedBy="address")
*/
private $organization;
public function setId($id) {
$this->id = $id;
}
public function getId() {
return ($this->id > 0) ? $this->id : $this->location->getId();
}
public function getStreet() {
return $this->street;
}
public function setStreet($street) {
$this->street = $street;
}
public function getNumber() {
return $this->number;
}
public function setNumber($number) {
$this->number = $number;
}
public function getCity() {
return $this->city;
}
public function setCity($city) {
$this->city = $city;
}
public function getPostalCode() {
return $this->postalCode;
}
public function setPostalCode($postalCode) {
$this->postalCode = $postalCode;
}
public function getCountry() {
return $this->country;
}
public function setCountry($country) {
$this->country = $country;
}
public function getLocation() {
return $this->location;
}
public function setLocation($location) {
$this->location = $location;
}
public function getOrganization() {
return $this->organization;
}
public function addOrganization($organization) {
$this->organization->add($organization);
}
public function __construct() {
$this->organization = new \Doctrine\Common\Collections\ArrayCollection;
}
и для организационного блока
/**
* @Entity
* @table(name="OrganizationalUnit")
*/
class Application_Model_Organizationalunit {
/**
* @id
* @column(type="integer")
* @generatedValue
*/
private $id;
/** @column(length=100) */
private $name;
/**
* @ManyToOne(targetEntity="Application_Model_Organizationalunittype",
* inversedBy="id")
* @JoinColumn(name="type",
* referencedColumnName="id")
*/
private $type;
/**
* @ManyToOne(targetEntity="Application_Model_Address", inversedBy="organization")
* @JoinColumn(name="address", referencedColumnName="id")
*/
private $address;
/**
* @OneToOne(targetEntity="Application_Model_Organizationalunit")
* @JoinColumn(name="parentId",
* referencedColumnName="id")
*/
private $parentId;
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function getType() {
return $this->type;
}
public function setType($type) {
$this->type = $type;
}
public function getAddress() {
return $this->address;
}
public function setAddress($address) {
$this->address = $address;
}
public function getParentId() {
return $this->parentId;
}
public function setParentId($parentId) {
$this->parentId = $parentId;
}
Я действительно не знаю, что с ним не так, эта проблема возникает не только здесь, но и когда у меня есть отношение ManyToMany, и я вставляю обе стороны в один флеш.
Edit:
А также я замечаю, что когда я сохраняю и сбрасываю только адрес и местоположение, и изменяю их после сброса, только у местоположения есть идентификатор, а адрес равен нулю (до сброса он равен NULL).
Спасибо за ваше время.