0

在我的應用程序中,我有一個有8個插槽的雪茄保溼盒。我希望每個插槽可容納一個可供選擇的數百支雪茄中的任何一個的實例。我可以爲一個雪茄盒添加一支雪茄到雪茄插槽,但我不能換到另一個雪茄盒並添加相同的雪茄到slot1。我在考慮在不同的雪茄櫃中,它肯定不是問題,但我現在得到例外"An exception occurred while executing 'UPDATE humidor SET slot_1 = ? WHERE id = ?' with params [2, 8]:SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2' for key 'UNIQ_4AE64E7F3CF622F8'"'我不完全是教條的專家,我不完全確定我應該如何去建模這個問題。任何建議都會很棒。Symfony關係映射多對一

這裏是插槽

/** 
* Humidor 
* 
* @ORM\Table(name="humidor") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\HumidorRepository") 
*/ 

class Humidor 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

/** 
* @ORM\ManyToOne(targetEntity="UserBundle\Entity\User", inversedBy="humidors") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
private $user; 

/** 
* @ORM\OneToOne(targetEntity="Cigar") 
* @ORM\JoinColumn(name="slot_1", referencedColumnName="id") 
*/ 
private $slot1; 

/** 
* @ORM\OneToOne(targetEntity="Cigar") 
* @ORM\JoinColumn(name="slot_2", referencedColumnName="id") 
*/ 
private $slot2; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_3", referencedColumnName="id") 
    */ 
private $slot3; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_4", referencedColumnName="id") 
    */ 
private $slot4; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_5", referencedColumnName="id") 
    */ 
private $slot5; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_6", referencedColumnName="id") 
    */ 
private $slot6; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_7", referencedColumnName="id") 
    */ 
private $slot7; 

    /** 
    * @ORM\OneToOne(targetEntity="Cigar") 
    * @ORM\JoinColumn(name="slot_8", referencedColumnName="id") 
    */ 
private $slot8; 

,然後我的雪茄實體

/** 
* Cigar 
* 
* @ORM\Table(name="cigar") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CigarRepository") 
* @ORM\HasLifecycleCallbacks() 
*/ 
class Cigar 
{ 
    /** 
    * @ORM\PrePersist() 
    */ 
    public function onPrePersist(){ 
     $this->setName($this->getManufacturer()->getName() . " " . $this->getVariant()); 
} 

/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var int 
* 
* @ORM\Column(name="gauge", type="integer") 
*/ 
private $gauge; 

/** 
* @var string 
* 
* @ORM\Column(name="body", type="string", length=255) 
*/ 
private $body; 

/** 
* @var string 
* 
* @ORM\Column(name="wrapper_country", type="string", length=255) 
*/ 
private $wrapperCountry; 

/** 
* @var string 
* 
* @ORM\Column(name="variant", type="string", length=255) 
*/ 
private $variant; 

/** 
* @var string 
* 
* @ORM\Column(name="description", type="text") 
*/ 
private $description; 

/** 
* @var string 
* 
* @ORM\Column(name="filler_country", type="string", length=255) 
*/ 
private $fillerCountry; 

/** 
* @ORM\ManyToOne(targetEntity="Manufacturer", inversedBy="cigars") 
* @JoinColumn(name="manufacturer_id", referencedColumnName="id") 
*/ 
private $manufacturer; 

/** 
* @ORM\ManyToOne(targetEntity="Wrapper", inversedBy="cigars") 
* @JoinColumn(name="wrapper_id", referencedColumnName="id") 
*/ 
private $wrapper; 

/** 
* @ORM\ManyToOne(targetEntity="Shape", inversedBy="cigars") 
* @JoinColumn(name="shape_id", referencedColumnName="id") 
*/ 
private $shape; 

/** 
* @ORM\Column(type="string") 
* 
*/ 
private $image; 

/** 
* @var string 
* @ORM\Column(type="string") 
*/ 
private $name; 

回答

0

雪茄盒當你有一個一對一的映射,學說創建這些列的唯一索引。讓我們考慮這個例子(我只留下一個插槽,因爲它足以讓這個例子):

id slot_1 
1  11 
2  12 

這意味着你有2支雪茄與分配分別雪茄盒12標識1112。這裏的slot_1欄有獨特的索引 - 這可以保證任何一支雪茄不屬於兩個不同的雪茄盒。產生

如果你嘗試切換它們,下面的SQL語句:

UPDATE humidors SET slot_1 = 12 WHERE id = 1; 
UPDATE humidors SET slot_1 = 11 WHERE id = 2; 

不幸的是,第一個語句不能被執行,因爲數據庫不允許雪茄12既符合雪茄盒12一次。

最簡單的解決方案是將一對一關係更改爲多對一關係(在您的$slotX字段中) - 這將刪除唯一的約束條件,否則它將在您的示例中起到相同的作用,因爲沒有反向關係。此外,由於有8個插槽,雪茄不能屬於其中的幾個(如果我正確理解的話),規則已經不被數據庫本身嚴格控制。

另一種方法是使用臨時空值等來切換它們,但對於教條更加困難,因爲您需要兩個單獨的刷新語句,並且可以選擇手動將它們包裝在事務中以避免數據庫中的狀態不一致。