Привет всем! Подскажите, пожалуйста, что может быть причиной ошибки ContextErrorException: Warning: spl_object_hash() expects parameter 1 to be object, null given in /home/dsazz/sites/postformula.ua/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 1588 – при обновлении данных уже существующей сущности User. Даже если юзер ничего не изменяет в форме, то все равно выкидивается данный Exception.
Привожу исходный код контроллера :
public function editAction()
{
$request = $this->getRequest();
$container = $this->container;
$userManager = $this->get('fos_user.user_manager');
$dispatcher = $container->get('event_dispatcher');
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('PostformulaMainBundle:User')
->find($request->request->get('id_user'));
if (!$user) {
throw $this->createNotFoundException('Такого юзера нет.');
}
$form = $this->createForm(new UserType(), $user);
$form->bind($request);
if ($form->isValid()) {
$em->persist($user);
$em->flush();
return new JsonResponse(array('status' => 'ok'));
} else {
return new JsonResponse(array('status' => 'fail', 'errors' => $this->getErrorMessages($form)));
}
}
Конфигурация Doctrine для сущности User:
Postformula\MainBundle\Entity\User:
type: entity
repositoryClass: Postformula\MainBundle\Entity\Repository\UserRepository
table: fos_user
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
phone:
type: string
length: 20
nullable: true
confirm_string:
type: string
length: 64
nullable: true
sms_code:
type: string
length: 4
nullable: true
confirm_sms:
type: boolean
length: 1
nullable: true
oneToOne:
avatar:
targetEntity: Postformula\MainBundle\Entity\Image
#cascade: ["persist", "remove"]
cascade: ["persist", "remove", "remove"]
#orphanRemoval: true
joinColumn:
name: avatar_id
referencedColumnName: id
onDelete: SET NULL
oneToMany:
createdFiles:
targetEntity: Postformula\MainBundle\Entity\Image
mappedBy: creator
cascade: ["persist", "remove", "remove"]
#cascade: ["persist", "remove"]
passportFiles:
targetEntity: Postformula\MainBundle\Entity\Image
mappedBy: userPassport
cascade: ["persist", "remove", "remove"]
#cascade: ["persist", "remove"]
createdProjects:
targetEntity: Postformula\MainBundle\Entity\Project
mappedBy: responsible
cascade: ["persist", "remove", "remove"]
#cascade: ["persist", "remove"]
permissions:
targetEntity: Postformula\MainBundle\Entity\ProjectPermission
mappedBy: user
cascade: ["persist", "remove", "remove"]
#cascade: ["persist", "remove"]
manyToMany:
projects:
targetEntity: Postformula\MainBundle\Entity\Project
cascade: ["persist", "merge", "remove"]
inversedBy: users
joinTable:
name: users_projects
joinColumns:
user_id:
referencedColumnName: id
onDelete: CASCADE
inverseJoinColumns:
project_id:
referencedColumnName: id
onDelete: CASCADE
groups:
targetEntity: Group
cascade: ["persist", "remove", "remove"]
joinTable:
name: fos_user_group
joinColumns:
user_id:
referencedColumnName: id
onDelete: CASCADE
inverseJoinColumns:
group_id:
referencedColumnName: id
onDelete: CASCADE
Исходный код самой формы UserType:
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Postformula\MainBundle\Entity\User;
use Postformula\MainBundle\Entity\Image;
use Postformula\MainBundle\Form\DataTransformer\StringToArrayTransformer;
use Postformula\MainBundle\Form\DataTransformer\EntityToIdTransformer;
use Postformula\MainBundle\Form\Project\ProjectChoiceType;
use Doctrine\ORM\EntityRepository;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new StringToArrayTransformer();
$builder->add('username', null, array(
'label' => 'Username',
'translation_domain' => 'FOSUserBundle'
));
$builder->add('email', 'email', array(
'label' => 'Email',
'translation_domain' => 'FOSUserBundle'
));
$builder->add('phone', 'text', array(
'label' => 'Phone'
));
$builder->add('avatar', new ImageType());
$builder->add('passportFiles', 'collection', array(
'type' => new ImageType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'label' => 'Passport Files',
));
$builder->add('groups', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'PostformulaMainBundle:Group',
'property' => 'label',
'multiple' => false,
'expanded' => true,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('g')
->where("g.name != :group_name")
->setParameter('group_name', "GROUP_SUPER_ADMIN")
->orderBy("g.id", "DESC");
},
'label' => false,
),
'allow_add' => true,
'prototype_name' => '__group__'
));
$builder->add('projects', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'PostformulaMainBundle:Project',
'property' => 'title',
'label' => 'Проект: '
),
'allow_add' => true,
'prototype_name' => '__project__',
));
$builder->add('permissions', 'collection', array(
'type' => new ProjectPermissionType(),
'allow_add' => true,
'allow_delete' => true,
'label' => false,
'required' => false,
));
// Crop start coordinate
$builder->add('x1', 'hidden', array(
"mapped" => false,
'data' => "100"
));
$builder->add('y1', 'hidden', array(
"mapped" => false,
'data' => "150"
));
//-----------------------------------
// Crop size
$builder->add('x2', 'hidden', array(
"mapped" => false,
'data' => "200"
));
$builder->add('y2', 'hidden', array(
"mapped" => false,
'data' => "200"
));
//-----------------------------------
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Postformula\MainBundle\Entity\User',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// уникальный ключ для генерации секретного токена
'intention' => 'task_azzOff',
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Postformula\MainBundle\Entity\User',
'cascade_validation' => true,
'roles' => null,
'validation_groups' => array('CreateUser'),
)
);
}
public function getName()
{
return 'user';
}
}