【发布时间】:2011-09-03 08:58:52
【问题描述】:
我正在使用 Doctrine 2 ORM,我遇到了这个问题。
我有三个实体,Address、Location 和 OrganizationalUnit。
它们之间的关系是: 地址 (OneToOne) 位置, 组织单位 (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 服务器日志中得到它)
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
哪个是错的,因为“('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 关系并且我将两边都插入一个冲洗时。
编辑: 而且我还注意到,当我坚持并仅刷新地址和位置,并在刷新后对它们进行 vardump 时,只有位置的 ID 和地址为零(在刷新之前它为 NULL)。
【问题讨论】:
-
你能显示
$address->addOrganization($organization);方法和$organization->setAddress($address);方法的代码吗?看起来这些方法有问题。 -
刚刚添加。感谢您的宝贵时间。
标签: php orm doctrine foreign-keys