学说2:ORM,刷新后为零外键

时间:2011-05-27 12:18:41

标签: php orm doctrine foreign-keys

我正在使用Doctrine 2 ORM,我遇到了这个问题。

我有三个实体,地址位置 OrganizationalUnit

他们之间的关系是:    地址(OneToOne)位置,    OrganizationalUnit (ManyToOne)地址。

问题: 当我试图保留所有对象(代码如下)时,它将OrganizationalUnit(FK: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)“这个零(下面的数据库模型)

Databes看起来像这样:

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;
}

对于OrganizationalUnit

/**
 * @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)。

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

这不起作用,因为你有两次声明地址和组织之间的关系。

将组织更改为:

/**
 * @Entity
 * @table(name="OrganizationalUnit")
 */
class Application_Model_Organizationalunit {

    ...

    /**
     * @ManyToOne(targetEntity="Application_Model_Address", inversedBy="organisation")
     * @JoinColumn(name="address", referencedColumnName="id")
     */
    private $address;

    ...
}

/**
 * @Entity
 * @table(name="Address")
 */
class Application_Model_Address {

    ...

    /**
     * @OneToMany(targetEntity="Application_Model_Organizationalunit", mappedBy="address")
     */
    private $organization;
}

修改 查看您的位置模型并找到以下行:

/**
 * @OneToOne(targetEntity="Application_Model_Location", inversedBy="address")
 * @JoinColumn(name="id", referencedColumnName="id")
 */
private $location;

您将自己的位置引用到自动增量的主键。它可以与此有关吗?您可能需要在地址表中添加location_id列。现在,您为id列分配两次值。

聚苯乙烯。看起来有更多东西不能正常工作,所以必须尝试一次解决一个问题。