Я использую модуль доктрины zfcuser для моего проекта zf2 с bjyauthorize, который работает довольно хорошо. Теперь я хотел бы получить подключенную сущность Country из моей сущности User
в User.php:
/**
* An example of how to implement a role aware user entity.
*
* @ORM\Entity
* @ORM\Table(name="users", indexes={
* @ORM\Index(name="fk_User_Country1_idx", columns={"Country_id"}),
* }, uniqueConstraints={@ORM\UniqueConstraint(name="email_UNIQUE", columns={"email"})})
* @ORM\HasLifecycleCallbacks()
*/
class User implements UserInterface, ProviderInterface
{
...
/**
* @var ersEntity\Country
* @ORM\ManyToOne(targetEntity="Country", inversedBy="users")
* @ORM\JoinColumn(name="Country_id", referencedColumnName="id")
*/
protected $country;
в Country.php
/**
* Entity\Country
*
* @ORM\Entity()
* @ORM\Table(name="Country")
* @ORM\HasLifecycleCallbacks()
*/
class Country implements InputFilterAwareInterface
{
...
/**
* @ORM\OneToMany(targetEntity="User", mappedBy="country")
* @ORM\JoinColumn(name="id", referencedColumnName="Country_id")
*/
protected $users;
Простое действие testAction в одном из моих контроллеров завершается ошибкой:
$user = $em->getRepository("ersEntity\Entity\User")
->findOneBy(array('id' => 1));
error_log($user->getFirstname().' '.$user->getSurname());
error_log('country: '.$user->getCountry()->getName());
что приводит к:
[Tue May 19 00:02:44 2015] [error] [client 185.17.207.16] Andi N.
[Tue May 19 00:02:44 2015] [error] [client 185.17.207.16] PHP Fatal error: Call to a member function getName() on a non-object in /home/ers/www/ers/module/Admin/src/Admin/Controller/TestController.php on line 172
Мне интересно, почему невозможно получить сущность Country от сущности User. С другими объектами в этом же проекте это работает нормально.
Может кто-нибудь сказать мне, что нужно сделать, чтобы иметь возможность вывести сущность Country из этой сущности zfcuser-bjyauthorize-doctrine User?
Для получения дополнительной информации о коде, весь этот проект доступен на https://github.com/inbaz/ers в развивающейся отрасли.
РЕДАКТИРОВАТЬ:
С пользователями, у которых не установлена страна, должна быть ошибка. Это верно, что нужно проверить, существует ли страна. Но у этого пользователя есть набор стран. Я проверил это через phpmyadmin. Получить объект этой страны невозможно с помощью метода getCountry ().
Возможно, это является причиной десериализации и сериализации доктрины в сеансе. Я проверил доктрина документации о том, как сохранить сущности в сеансе. Но я бы хотел сохранить все элементы в сеансе, поэтому в моем случае в сеансе есть объект заказа, который содержит несколько объектов пакета. Каждый объект пакета имеет одного пользователя и несколько объектов элемента. Возвращая сущность заказа из сеанса, я хотел бы иметь доступ ко всем этим элементам.
Я даже пытался сделать слияние для каждого пользователя в сеансе, как:
foreach($participants as $participant) {
$participant = $em->merge($participant);
}
но это ничего не меняет. Даже объединение всего заказа не было успешным.
У вас есть идея о том, как вернуть сущности доктрины из сеанса с полными функциями доктрины?
Это выглядит хорошо для меня. Сначала я думал, что ваш getCountry
метод отсутствовал в определении вашей сущности, но я вижу это там.
Я предполагаю, что пользователь с идентификатором 1 не имеет установленной страны. Иди к своему столу (phpmyadmin
или что-то еще) и проверьте значение Country_id
колонка.
Если вы хотите, чтобы у каждого пользователя была страна, вы можете обеспечить целостность данных, добавив nullable=false
к вашему определению столбца соединения согласно Учение2 @JoinColumn
функции.
В противном случае (если $country
разрешено быть null
Вы должны сначала проверить, является ли страна объектом, прежде чем тянуть getName()
:
$countryName = null;
$country = $user->getCountry();
if(is_object($country)){
$countryName = $country->getName();
}
/** @var null|string $countryName */
$countryName //... use your country name which is null or string
Еще одна вещь, я настоятельно рекомендую использовать только в нижнем регистре строки для Таблица а также колонка имена. Использование заглавных букв может привести к неприятностям.
Я посмотрел поближе и теперь вижу, что ваши отображения неверны. Ты использовать доктрину для проверки вашей схемы? Eсть @ORM\JoinColumn
на обратной стороне отношений (внутри Country.php). Обратная сторона не нуждается в этом @ORM\JoinColumn
declariation. Вы должны удалить эту строку. Сторона-владелец — Пользователь, поэтому определение столбца соединения должно быть объявлено только там.
Должно быть так:
Country.php:
/**
* @var Collection
* @ORM\OneToMany(targetEntity="User", mappedBy="country")
*/
protected $users;
User.php:
/**
* @var Country
* @ORM\ManyToOne(targetEntity="Country", inversedBy="users")
* @ORM\JoinColumn(name="Country_id", referencedColumnName="id")
*/
protected $country;
Доктрина 2: Можно ли сохранять сущности в сеансах?
Это ответ на мой вопрос.
если загруженный объект не загружается во время сериализации, он не будет загружен после десериализации. Поэтому перед сериализацией необходимо убедиться, что объект полностью загружен.
По-прежнему остается открытым вопрос, нельзя ли создать новую сущность доктрины, получить копию массива десериализованной сущности и заполнить эти данные новой сущностью.