2014-01-24 4 views
1

У меня проблема с вставкой объекта пользователя с связанным объектом UserProfile.Symfony2 Doctrine insert entity with related - NOT UPDATE

class User 
{ 
/** 
* @var integer 
* 
* @ORM\Id 
* @ORM\Column(name="id", type="integer", options={"unsigned"=true}) 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @var UserProfile 
* 
* @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade={"persist", "remove"}) 
*/ 
protected $profile 
.... 
} 


class UserProfile 
{ 
/** 
* @var User 
* 
* @ORM\Id 
* @ORM\GeneratedValue 
* @ORM\OneToOne(targetEntity="User", inversedBy="profile") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
protected $user; 
..... 
} 

Стандартное двунаправленное отношение User-UserProfile. Когда я отправляю форму, содержит поля из объекта User и объекта UserProfile, $ form-> getData() дает мне объект User с UserProfile. Все идет нормально.

Mysql генерирует уникальный идентификатор с помощью автоинкремента PK. Чтобы вставить объект, я должен:

$em->persist($user) 
$em->flush() 

Чтобы получить PK как идентификатор для сохранения и очистки пользовательского файла.

Но доктрина CANT вставки $ пользователь, потому что объект $ пользователь связанные $ user-> профиль, полученный от формы Типа:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
    ->add('email', 'email', array('label' => 'email')) 
    ->add('profile', new RegistrationProfileFormType(), array('required'=>true,)) 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'User', 
     'cascade_validation'=>true, 
    )); 
} 

Update: Исключение тзда Entity типа Entity \ UserProfile имеет идентичность через иностранный объект Entity \ User, однако этот объект не имеет самоидентификации. Вы должны вызвать EntityManager # persist() для связанного объекта и убедиться, что был создан идентификатор, прежде чем пытаться сохранить «Entity \ UserProfile». В случае создания Post Insert ID Generation (например, MySQL Auto-Increment или PostgreSQL SERIAL) это означает, что вы должны вызывать EntityManager # flush() между обеими персистентными операциями.

Вопрос: Как правильно обращаться с этой проблемой?

Извините за мой ржавый английский.

+0

Какое сообщение об исключении вы получаете при попытке отправить свою форму? – nifr

+0

Проблема в том, как очистить объект от связанных для первого флеша, когда нет PK/id для связанных. Я сделал некоторое грязное обходное решение, но считаю, что это не так./ ** @ PrePersist { – d3uter

+0

User Entity: /** @ ORM \ PrePersist */onPrePersist {unset ($ this-> profile)} и внутри контроллера $ profile = $ user-> getProfile(); $ Em-> сохраняются ($ пользователю); $ em-> flush ($ user); $ User-> setProfile ($ профиль); $ em-> flush ($ user) – d3uter

ответ

1

Проблема в том, что вы собираетесь перемещать объекты через не принадлежащую стороне. Собственная сторона имеет свойство «inverseedBy». И вы должны упорствовать в объектах.

Вы можете прочитать об этом здесь: http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html

Так, например, для вашего случая:

$profile->setUser($user); 
$em->persist($profile). 
$em->flush(); 

Хотя, если вы хотите сохранить путь у вас уже есть, есть два варианта:

1) Сделать User объект как владеющему стороне и UserProfile как обратная сторона

или

2) В своем профиле сеттер в User классе сделать что-то вроде этого:

public function setUserProfile(UserProfile $profile) 
{ 
    $this->profile = $profile; 
    $this->profile->setUser($this); 
} 

редактировать:

Я просто заметил, что вы не имеете поле «ID» в вашей UserProfile Сущность - возможно, это и есть причина. самым простым способом могут быть отдельные первичные и внешние ключи. Но если вы хотите рассматривать иностранные как первичные, взгляните на эту статью: http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#identity-through-foreign-entities

+0

Привет. Я хочу сохранить сопоставление, потому что таким образом у меня есть внешний ключ UserProfile как User PK. Это невозможно, если я изменю владельца на пользователя. Да, я знаю о двунаправленном обновлении, и у меня установлен сеттер, как вы описали. Doctrine cant вставляет UserProfile без id/PK, и это невозможно без PK для пользователя. Закрытый круг – d3uter

+0

Итак, просто добавьте cascade = {"persist"} в "user" mapping в вашем UserProfile, и это должно помочь. – Cyprian

+0

Я надеялся, что это все, но все же такое же исключение. :/ – d3uter

Смежные вопросы