Отношение доктрины symfony 2 OneToOne

Как получить и установить объект, для которого OneToOne отношение, как в моем примере.

У меня ошибка:

Для объекта типа Miejsce\ObiektyBundle\Entity\UsersInformation отсутствует назначенный идентификатор для поля "user_id". Стратегия генерации идентификатора для этого объекта требует, чтобы поле ID было заполнено до вызова EntityManager#persist(). Если вместо этого вам нужны автоматически сгенерированные идентификаторы, вам необходимо соответствующим образом настроить сопоставление метаданных.

в контроллере php - я пытаюсь сохранить новый элемент таким образом:

$product = new Userstest();
$product->setUsername('aa')->setPassword('123456');
$product->setInformation((new UsersInformation())->setCompany('firma'));
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();

когда я сохраняю таким образом

$code = 'test3';
    
    $product->setUsername($code)->setPassword('123456');
    $information = new UsersInformation();
    $information
        ->setEmail($code.'@a.pl')
        ->setUserId($product->getUserId())
    ;


    $product->setInformation($information);


    $em = $this->getDoctrine()->getManager();
    $em->persist($product);
    $em->flush();

 print_r($product);

и имеют

`* @ORM\GeneratedValue(strategy="AUTO") UsersInformation.for` `user_id`

имеют :

Miejsce\ObiektyBundle\Entity\Userstest Object
(
    [user_id:protected] => 9
    [information:protected] => Miejsce\ObiektyBundle\Entity\UsersInformation Object
        (
            [user_id:protected] => 5
            [user:protected] => 
            [email] => [email protected]
            [gender] => 
            [company] => 
        )

    [username:protected] => test3
    [password:protected] => 123456
)

Не работает но когда удаляю * @ORM\GeneratedValue(strategy="AUTO")

Я получаю такую ​​ошибку:

Для объекта типа Miejsce \ ObiektyBundle \ Entity \ UsersInformation отсутствует назначенный идентификатор для поля user_id. Стратегия генерации идентификатора для этого объекта требует, чтобы поле ID было заполнено до вызова EntityManager # persist (). Если вместо этого вам нужны автоматически сгенерированные идентификаторы, вам необходимо соответствующим образом скорректировать сопоставление метаданных.

Miejsce\ObiektyBundle\Entity\Userstest Object
(
    [user_id:protected] => 9
    [information:protected] => Miejsce\ObiektyBundle\Entity\UsersInformation Object
        (
            [user_id:protected] => 5
            [user:protected] => 
            [email] => [email protected]
            [gender] => 
            [company] => 
        )

    [username:protected] => test3
    [password:protected] => 123456
)

Сущности:

<?php
namespace Miejsce\ObiektyBundle\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity
 * @ORM\Table(name="test_user")
 */
class Userstest
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 *
 */
protected $user_id;


/**
 * @ORM\OneToOne(targetEntity="UsersInformation", mappedBy="Users", cascade={"persist", "remove"})
 */
protected $information;


/**
 * @ORM\Column(type="string", length=255)
 */
protected $username;


/**
 * @ORM\Column(type="string", length=32)
 */
protected $password;

<?php
namespace Miejsce\ObiektyBundle\Entity;
 
use Doctrine\ORM\Mapping as ORM;


/**
 * @ORM\Entity
 * @ORM\Table(name="test_userInfo")
 */
class UsersInformation
{

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 */
protected $user_id;

/**
 * @ORM\OneToOne(targetEntity="Userstest", inversedBy="information")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
 */
protected $user;


/**
 * @ORM\Column(type="string", length=255)
 */
public $email;

/**
 * @ORM\Column(type="string", length=1)
 */
public $gender;

/**
 * @ORM\Column(type="string", length=255)
 */
public $company;

person Developer    schedule 18.12.2013    source источник


Ответы (2)


Добавьте @ORM\GeneratedValue(strategy="AUTO") к $user_id в вашем UserInformation классе или используйте setUserId, чтобы установить явный идентификатор для вашей сущности.

Объяснение:

Ошибка сообщает вам, что Doctrine требуется идентификатор (первичный ключ вашей сущности), прежде чем она сможет сохранить сущность в базе данных. Таким образом, вы должны установить идентификатор или позволить доктрине сгенерировать идентификатор для вас. С помощью аннотации @ORM\GeneratedValue(strategy="AUTO") вы говорите Doctrine создать соответствующий идентификатор для этой сущности и не беспокоиться об этом.

Изменить:

Если вы хотите реализовать, что Userstest и Usersinformation имеют одинаковый идентификатор, вы можете сделать это так:

$em = $this->getDoctrine()->getManager();

$product = new Userstest();
$product->setUsername('aa')->setPassword('123456');

$em->persist($product);
$em->flush();

$information = new UsersInformation();
$information->setCompany('firma');
$information->setUserId($product->getUserId()); // Set the User Id

$product->setInformation($information);

$em->persist($information);
$em->persist($product);
$em->flush();
person Syjin    schedule 18.12.2013
comment
но мне нужно Userstest.user_id == UsersInformation.user_id, поэтому, когда я помещаю нового пользователя, новый UsersInformation получает идентификатор от пользователя - как это сделать? - person Developer; 18.12.2013
comment
отредактировал мой ответ ... проверьте, решает ли это вашу проблему. - person Syjin; 18.12.2013
comment
Я редактирую запрос - оба способа не выглядят так, как мне нужно - user_id для UsersInformation не заполнен - ​​я должен сначала сохранить Userstest, а затем добавить UsersInformation, чтобы получить идентификатор? невозможно, чтобы это значение было автоматическим? - person Developer; 18.12.2013
comment
Ты прав. Сначала вы должны сохранить Userstest, чтобы у него был идентификатор. Я обновил свой пример кода. Чтобы автоматически назначить тот же идентификатор, проверьте ссылку в ответе Рене Терстегена. Но, честно говоря, я бы, вероятно, порекомендовал объединить их с объектами в одну (если возможно). - person Syjin; 18.12.2013
comment
я пытаюсь добиться успеха в witchout: stackoverflow.com/questions/20663942/ - person Developer; 18.12.2013

Если у вас есть свобода изменять базу данных в соответствии с вашими потребностями, я бы выбрал базовую реализацию отношения «один-к-одному» (что означает дополнительный столбец в одной из ваших таблиц) и отказался бы от необходимости совместного использования идентификаторов.

Если вы настаиваете, возможно, приведенная ниже ссылка является решением (зависит от версии Doctrine2, которую вы используете):

http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-dehibited-identity

В документации указано:

Идентификация через иностранные объекты поддерживается только в Doctrine 2.1.

Я не уверен, означает ли это, что он поддерживается только в версии 2.1 или поддерживается начиная с версии 2.1.

И помните, что такие решения имеют меньшую производительность по сравнению с обычными индивидуальными отношениями.

person Rene Terstegen    schedule 18.12.2013
comment
я пытаюсь добиться успеха в witchout: stackoverflow.com/questions/20663942/ - person Developer; 18.12.2013