我有配置文件和研究。一個人可以完成很多研究。表單呈現正確。有一個按鈕「添加新的研究」,並與jQuery我添加基於數據原型的另一個子窗體,這很好。當我提出這樣的形式與新的子窗體,我得到一個數據庫錯誤Symfony2形式和Doctrine2 - 更新分配的實體中的外鍵失敗[解決]
Integrity constraint violation: 1048 Column 'profile_id' cannot be null
我明白了這個錯誤,但我不知道如何擺脫它。我知道我可以在控制器中綁定後更新研究集合,但我希望有一種方法可以在註釋中正確配置它。當我只更新實體時,一切正常。
的代碼是:
class Profile {
/**
* @var integer $profileId
*
* @ORM\Column(name="profile_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $profileId;
...
/**
*
* @var Study
* @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"persist", "remove"})
*/
private $study;
public function __construct()
{
$this->study = new \Doctrine\Common\Collections\ArrayCollection();
}
...
}
和
class Study {
/**
* @var integer $studyId
*
* @ORM\Column(name="study_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $studyId;
...
/**
* @var Profile
*
* @ORM\ManyToOne(targetEntity="Profile")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="profile_id", referencedColumnName="profile_id")
* })
*/
private $profile;
...
}
以s(G)埃特斯。墊層數據庫結構是
CREATE TABLE IF NOT EXISTS `profile` (
`profile_id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`profile_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `study` (
`study_id` int(11) NOT NULL AUTO_INCREMENT,
`profile_id` int(11) NOT NULL,
PRIMARY KEY (`study_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `study`
ADD CONSTRAINT `study_fk2` FOREIGN KEY (`profile_id`) REFERENCES `profile` (`profile_id`);
形式buidlers是:
class ProfileType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('study', 'collection', array(
'type' => new StudyType(),
'allow_add' => true,
'allow_delete' => true
)
)
}
...
}
和
class StudyType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('city') //example field not included in above structures
}
...
}
JavaScript部分
function profileNewStudy() {
var nr = $('[class^=profile_study_][class*=type2]').last().parent();
nr = nr.attr('id').split('_');
nr = nr.pop()*1 + 1;
var proto = $('#profile_study').data('prototype');
proto = proto.replace(/\$\$name\$\$/g, nr);
$('#profile_study').append(proto).find('.profile_study_' + nr + ' input').val('qpa' + nr);
}
和嫩枝模板
<form action="#" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" value="Zapisz"/>
</form>
出於測試目的,我從數據庫約束中刪除了study.profile_id上的NOT NULL,然後除了study.profile_id = null之外,一切都保存了。
@Gremo答案
我做了一些測試之後,編輯。遺憾的是它並沒有幫助:(我糾正了自己的錯誤,代碼
class Profile
/**
* @var Study
* @ORM\OneToMany(targetEntity="Study", mappedBy="profile")
*/
private $study;
class Study
/**
* @var Profile
* @ORM\ManyToOne(targetEntity="Profile", inversedBy="study")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE", referencedColumnName="profile_id")
*/
private $profile;
,當我在形式上增加了新的研究實體,並將其發佈到服務器我得到了一個錯誤:一個新的實體是通過關係「奧爾登發現\ xxxBundle \ Entity \ Profile#study'未配置爲級聯實體的持久化操作:Alden \ xxxBundle \ Entity \ Study @ 0000000073eb1a8b00000000198469ff。顯式持久化新實體或配置關係中的級聯持久化操作如果找不到實體導致問題實現'Alden \ xxxxBundle \ Entity \ Study #__ toString()'得到線索。
所以我添加級聯到配置文件:
/**
* @var Study
* @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"persist"})
*/
private $study;
而且我得到了像開始時的錯誤:SQLSTATE [23000]:完整性約束違規:1048列'profile_id'不能爲空。
編輯 我的控制器代碼:
$request = $this->getRequest();
$r = $this->getProfileRepository();
$profile = $id ? $r->find($id) : new \Alden\BonBundle\Entity\Profile();
/* @var $profile \Alden\BonBundle\Entity\Profile */
$form = $this->createForm(new ProfileType(), $profile);
if ($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if ($form->isValid())
{
$vacation = $profile->getVacation();
foreach($vacation as $v) {
$r=5;
}
$em = $this->getEntityManager();
$em->persist($profile);
$em->flush();
//return $this->redirect($this->generateUrl('profile_list'));
}
}
return array(
'profile' => $profile,
'form' => $form->createView()
);
SOLUTION
在Profile類,重要的部分是級聯,orphanRemoval在註釋和在setStudies foreach循環()(由於建議@ Parhs)
/**
* @var \Doctrine\Common\Collections\ArrayCollection
* @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"ALL"}, orphanRemoval=true)
*/
private $studies;
public function __construct()
{
$this->studies = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return Doctrine\Common\Collections\Collection
*/
public function getStudies()
{
return $this->studies;
}
public function setStudies($studies)
{
foreach ($studies as $v)
{
if (is_null($v->getProfile()))
{
$v->setProfile($this);
}
}
$this->studies = $studies;
}
I n Study class
/**
* @var Profile
* @ORM\ManyToOne(targetEntity="Profile", inversedBy="studies")
* @ORM\JoinColumn(name="profile_id", nullable=false, onDelete="CASCADE", referencedColumnName="profile_id")
*/
private $profile;
和通常的獲得者和設定者。
我做了同樣的測試 - 請在主線程的結果。 – koral
@koral對不起,我搞砸了擁有的東西。我要更新答案。 – gremo
我設法整理擁有的東西,你可以看到:)但問題仍然存在 – koral