2011-07-07 11 views
1

こんにちは、Stack Overflowのメンバー!Doctrine 2の1対多の関係ORMがリモートキーを挿入しない

私は現在、私を地面に動かしているドクトリン2の関係に問題があります。

私は、私のAnalyticsCampaignモデルと私のAnalyticsDataモデルの間でDoctrineの非常に素晴らしく単純な一対多関係を設定しようとしています。

以下は私のコードと私の問題です。

foreach($entries as $entry) 
{ 
    // Instance of AnalyticsCampaign model with data in it. 
    $campaign = $this->_getCampaignByGoogleId($entry['campaignId']);    
    $daysAgo = time() - $campaign->getUpdated(); 
    $dateCreated = time() - $campaign->getCreated(); 
    if($daysAgo>=86400 || $dateCreated < 86400) 
    { 
     // More or equal to 1 day has passed since last database update 
     // Let's insert these fuckers. 
     // Insert the new GA data. 

     $data = new Model_AnalyticsData(); 
     $data->fromArray($entry); 
     $data->setCampaign($campaign->getId()); 
     $campaign->data = array($data); 
     $this->em->persist($campaign); 

    } 
} 
$this->em->flush(); 

解析キャンペーンデータ

<?php 


/** 
* AnalyticsCampaign 
* 
* @Table(name="analyticsCampaign") 
* @Entity 
*/ 
class Model_AnalyticsCampaign 
{ 

    const STATUS_ACTIVE = 1; 

    const STATUS_INACTIVE = 0; 

    /** 
    * @var integer $id 
    * 
    * @Column(name="id", type="integer", nullable=false) 
    * @Id 
    * @GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var string $name 
    * 
    * @Column(name="name", type="string", length=255, nullable=true) 
    */ 
    private $name; 

    /** 
    * @var string $analyticsCampaignId 
    * 
    * @Column(name="analyticsCampaignId", type="integer", length=25, nullable=false) 
    */ 
    private $analyticsCampaignId; 


    /** 
    * @Column(type="integer") 
    */ 
    private $updated; 

    /** 
    * @Column(type="integer") 
    */ 
    private $created; 

    /** 
    * @Column(type="integer") 
    */ 
    private $status; 

    /** 
    * @OneToMany(targetEntity="Model_AnalyticsData", mappedBy="campaign", cascade={"persist"}) 
    * @param \Doctrine\Common\Collections\ArrayCollection $data 
    */ 
    private $data; 


    public function __construct() 
    { 
     $this->updated(); 
     $this->created = time(); 
     if(empty($this->status)) 
     { 
      $this->status = Model_AnalyticsCampaign::STATUS_INACTIVE; 
     } 
    } 

    public function updated() 
    { 
     $this->updated = time(); 
    } 

    public function created() 
    { 
     $this->created = time(); 
    } 

    public function getId() 
    { 
     return $this->id; 
    } 


    public function fromArray(array $array) 
    { 
     $objects = get_object_vars($this); 
     foreach($array as $item => $value) 
     { 
      if(array_key_exists($item, $objects)) 
      { 
       $this->$item = $value; 
      } 
     } 
    } 

    public function setUpdated() 
    { 
     $this->updated(); 
    } 

    public function getUpdated() 
    { 
     return ((!empty($this->updated)) ? $this->updated : 0); 
    } 

    public function setCreated() 
    { 
     $this->created(); 
    } 

    public function getCreated() 
    { 
     return ((!empty($this->created)) ? $this->created : 0); 
    } 

    public function setStatus($status) 
    { 
     $statusFlag = "SELF::STATUS_".strtoupper($status); 

     if(!defined($statusFlag)) 
     { 
      throw new \InvalidArgumentException("Status '$status' is not valid", 500); 
     } 

     $this->status = constant($statusFlag); 
    } 

    public function getStatus() 
    { 
     $constants = getActiveStatusConstants(); 

     if(isset($constants[$this->status])) 
     { 
      return $constants[$this->status]; 
     } 
    } 

    private function getActiveStatusConstants() 
    { 
     $vars = get_object_vars(); 

     $potentialStatus = array(); 
     foreach($vars as $var) 
     { 
      if(strpos("STATUS_") == 0) 
      { 
       // Matching all of our status variables. 
       $potentialStatus[] = array(
        constant("SELF::$var") => substr($var, 7, strlen($var)) 
       ); 
      } 
     } 

     return $potentialStatus; 
    } 
    public function __get($property) 
    { 
     return $this->$property; 
    } 

    public function __set($property,$value) 
    { 
     $this->$property = $value; 
    } 

} 

AnalyticsDataモデル

<?php 

/** 
* AnalyticsData 
* 
* @Table(name="analyticsData") 
* @Entity 
*/ 
class Model_AnalyticsData 
{ 
    public function __construct() 
    { 
     // constructor is never called by Doctrine 
     $this->created = $this->updated = time(); 
    } 



    /** 
    * @var integer $id 
    * 
    * @Column(name="id", type="integer", nullable=false) 
    * @Id 
    * @GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 


    /** 
    * @var integer $campaignrank 
    * 
    * @Column(name="campaignRank", type="integer", nullable=true) 
    */ 
    private $campaignRank; 

    /** 
    * @var decimal $cost 
    * 
    * @Column(name="cost", type="decimal", nullable=true) 
    */ 
    private $cost; 

    /** 
    * @var integer $impressions 
    * 
    * @Column(name="impressions", type="integer", nullable=true) 
    */ 
    private $impressions; 

    /** 
    * @var integer $clicks 
    * 
    * @Column(name="clicks", type="integer", nullable=true) 
    */ 
    private $clicks; 

    /** 
    * @var decimal $costperclick 
    * 
    * @Column(name="costPerClick", type="decimal", nullable=true) 
    */ 
    private $costPerClick; 

    /** 
    * @var integer $averagecampaignposition 
    * 
    * @Column(name="averageCampaignPosition", type="integer", nullable=true) 
    */ 
    private $averageCampaignPosition; 

    /** 
    * @Column(type="integer") 
    */ 
    private $created; 

    /** 
    * @Column(type="integer") 
    */ 
    private $updated; 

    /** 
    * 
    * Store a reference to the campaign that this relates to 
    * @ManyToOne(targetEntity="Model_AnalyticsCampaign", inversedBy="data") 
    * @JoinColumn(name="campaignId", referencedColumnName="id") 
    */ 
    protected $campaign; 


    public function fromArray(array $array) 
    { 
     $objects = get_object_vars($this); 
     foreach($array as $item => $value) 
     { 
      if(array_key_exists($item, $objects)) 
      { 
       $this->$item = $value; 
      } 
     } 
    } 

    /** 
    * @PreUpdate 
    */ 
    public function updated() 
    { 
     $this->updated = time(); 

    } 

    public function setCampaign($id) 
    { 
     $this->campaign = $id; 
    } 


} 

私が午前問題は、それが実際にしかし、それはdosen't、問題なく子テーブルのデータを追加しないことですAnalyticsData内にあるcampaignIdフィールドを入力します。

私は手動で試してみて、そのIDを設定するのではなく、それは私を提示し、それをやって:

Exception information: 

Message: A new entity was found through a relationship that was not configured to cascade persist operations: @. Explicitly persist the new entity or configure cascading persist operations on the relationship. 
Stack trace: 

#0 /usr/share/php/Doctrine/ORM/UnitOfWork.php(490): Doctrine\ORM\UnitOfWork->computeAssociationChanges(Array, 1) 
#1 /usr/share/php/Doctrine/ORM/UnitOfWork.php(505): Doctrine\ORM\UnitOfWork->computeChangeSet(Object(Doctrine\ORM\Mapping\ClassMetadata), Object(Model_AnalyticsData)) 
#2 /usr/share/php/Doctrine/ORM/UnitOfWork.php(249): Doctrine\ORM\UnitOfWork->computeChangeSets() 
#3 /usr/share/php/Doctrine/ORM/EntityManager.php(328): Doctrine\ORM\UnitOfWork->commit() 
#4 /home/tom/development/seo.qe.org/application/modules/default/controllers/AnalyticsController.php(64): Doctrine\ORM\EntityManager->flush() 
#5 /usr/share/php/Zend/Controller/Action.php(513): AnalyticsController->indexAction() 
#6 /usr/share/php/Zend/Controller/Dispatcher/Standard.php(295): Zend_Controller_Action->dispatch('indexAction') 
#7 /usr/share/php/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) 
#8 /usr/share/php/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch() 
#9 /usr/share/php/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run() 
#10 /home/tom/development/seo.qe.org/public/index.php(26): Zend_Application->run() 
#11 {main}     

Request Parameters: 

array (
    'controller' => 'analytics', 
    'action' => 'index', 
    'module' => 'default', 
)     

は、誰もがそうだとすれば、地球上で何が私が間違っているの、この前を見ています?

大変ありがとうございました。私は、1,000,000個のインターネットを手助けできる人に贈ります!

答えて

3

問題は、AnalyticsDataをAnalyticsCampaignに挿入し、次にAnaltyicsCampaignをAnalyticsDataに挿入する必要があるためです。

私はドクトリンを完全に間違った方法と考えていました。私はオブジェクトの観点から考える必要がありました。だから私がCampaignIdを挿入しようとしたとき、DoctrineはIDではなくObjectとの関係を確立しなければならないので失敗していました。

だから私のコードは、このよう終わった:

$data = new Model_AnalyticsData(); 
$data->fromArray($entry); 
$data->setCampaign($campaign); 
$campaign->data = array($data); 
$this->em->persist($campaign); 

だから、$キャンペーン単位>データがArrayObjectあるので、(それだけでオブジェクトを受け付けませんので、あなたは最初の配列でそれを配置する必要があります明らかにあなたが望む数の子エンティティを挿入できることを意味します)。

そうでした!

すべてのクレジットはfreenode IRCの#doctrineでBeberleiに送られます。

関連する問題