我在提交实体后遇到数据映射问题
实体:
<?php
namespace Site\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\EntityManager;
use JMS\Serializer\Annotation as Serializer;
use JMS\Serializer\Annotation\Groups;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* UserAddress
*
* @ORM\Table(name="user_address")
* @ORM\Entity
*
* @Serializer\ExclusionPolicy("all")
* ---------- SERIALIZER GROUPS -----
* all -- All entries
*/
class UserAddress
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
* @Serializer\Type("integer")
* @Serializer\Expose
* @serializer\SerializedName("ID")
* @serializer\Groups({"all"})
*/
public $ID;
/**
* @var integer
*
* @ORM\Column(name="user_id", type="integer", nullable=false)
*/
public $UserId;
/**
* @var integer
*
* @ORM\Column(name="level_id", type="integer", nullable=false)
*
* @Serializer\Type("integer")
* @Serializer\Expose
* @serializer\SerializedName("LevelId")
* @serializer\Groups({"all"})
*/
public $LevelId;
/**
* @var integer
*
* @ORM\Column(name="address_type_id", type="integer", nullable=false)
*
* @Serializer\Type("integer")
* @Serializer\Expose
* @serializer\SerializedName("AddressTypeId")
* @serializer\Groups({"all"})
*
* @Assert\NotBlank()
*/
public $AddressTypeId;
/**
* @var string
*
* @ORM\Column(name="address_data", type="text", nullable=false)
*
* @Serializer\Type("string")
* @Serializer\Expose
* @serializer\SerializedName("Address Data")
* @serializer\Groups({"all"})
*
* @Assert\NotBlank()
*/
public $AddressData;
/**
* @var integer
*
* @ORM\Column(name="public_yn", type="integer", nullable=false)
*
* @Serializer\Type("boolean")
* @Serializer\Expose
* @serializer\SerializedName("PublicYN")
* @serializer\Groups({"all"})
*
* @Assert\NotBlank()
*/
public $PublicYN;
/**
* @var integer
*
* @ORM\Column(name="primary_yn", type="integer", nullable=false)
*
* @Serializer\Type("boolean")
* @Serializer\Expose
* @serializer\SerializedName("PrimaryYN")
* @serializer\Groups({"all"})
*
* @Assert\NotBlank()
*/
public $PrimaryYN;
/**
* @ORM\ManyToOne(targetEntity="Site\UserBundle\Entity\UserMain", inversedBy="UserAddress")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
public $User;
/**
* @ORM\ManyToOne(targetEntity="Site\UserBundle\Entity\UserAddressType", inversedBy="UserAddress")
* @ORM\JoinColumn(name="address_type_id", referencedColumnName="address_type_id")
*
* @Serializer\Type("Site\UserBundle\Entity\UserAddressType")
* @Serializer\Expose
* @serializer\SerializedName("UserAddressType")
* @serializer\Groups({"all"})
*/
public $UserAddressType;
/**
* Get ID
*
* @return integer
*/
public function getID()
{
return $this->ID;
}
/**
* Set UserId
*
* @param integer $userId
* @return UserAddress
*/
public function setUserId($userId)
{
$this->UserId = $userId;
return $this;
}
/**
* Get UserId
*
* @return integer
*/
public function getUserId()
{
return $this->UserId;
}
/**
* Set LevelId
*
* @param integer $levelId
* @return UserAddress
*/
public function setLevelId($levelId)
{
$this->LevelId = $levelId;
return $this;
}
/**
* Get LevelId
*
* @return integer
*/
public function getLevelId()
{
return $this->LevelId;
}
/**
* Set AddressTypeId
*
* @param integer $addressTypeId
* @return UserAddress
*/
public function setAddressTypeId($addressTypeId)
{
$this->AddressTypeId = $addressTypeId;
return $this;
}
/**
* Get AddressTypeId
*
* @return integer
*/
public function getAddressTypeId()
{
return $this->AddressTypeId;
}
/**
* Set AddressData
*
* @param string $addressData
* @return UserAddress
*/
public function setAddressData($addressData)
{
$this->AddressData = $addressData;
return $this;
}
/**
* Get AddressData
*
* @return string
*/
public function getAddressData()
{
return $this->AddressData;
}
/**
* Set PublicYN
*
* @param integer $publicYN
* @return UserAddress
*/
public function setPublicYN($publicYN)
{
$this->PublicYN = $publicYN;
return $this;
}
/**
* Get PublicYN
*
* @return integer
*/
public function getPublicYN()
{
return $this->PublicYN;
}
/**
* Set PrimaryYN
*
* @param integer $primaryYN
* @return UserAddress
*/
public function setPrimaryYN($primaryYN)
{
$this->PrimaryYN = $primaryYN;
return $this;
}
/**
* Get PrimaryYN
*
* @return integer
*/
public function getPrimaryYN()
{
return $this->PrimaryYN;
}
/**
* Set User
*
* @param \Site\UserBundle\Entity\UserMain $user
* @return UserAddress
*/
public function setUser(\Site\UserBundle\Entity\UserMain $user = null)
{
$this->User = $user;
return $this;
}
/**
* Get User
*
* @return \Site\UserBundle\Entity\UserMain
*/
public function getUser()
{
return $this->User;
}
/**
* Set UserAddressType
*
* @param \Site\UserBundle\Entity\UserAddressType $userAddressType
* @return UserAddress
*/
public function setUserAddressType(\Site\UserBundle\Entity\UserAddressType $userAddressType = null)
{
$this->UserAddressType = $userAddressType;
return $this;
}
/**
* Get UserAddressType
*
* @return \Site\UserBundle\Entity\UserAddressType
*/
public function getUserAddressType()
{
return $this->UserAddressType;
}
}
表格是:
namespace Site\UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;
class UserAddressType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('UserId','hidden')
->add('LevelId', 'integer', array(
'label'=>'Sort Rate (Order)'
))
->add('AddressTypeId', 'entity', array(
'class'=>'SiteUserBundle:UserAddressType',
'query_builder'=> function(EntityRepository $er){
return $er->createQueryBuilder('t')
->orderBy('t.AddressDescription', 'ASC');
},
'property'=>'AddressDescription',
'label'=>'Address Type'
))
->add('AddressData', 'text')
->add('PublicYN', 'choice', array(
'choices' => array( 'false'=>'Private', 'true'=>'Public'),
'required'=>true,
'label'=>'Pubicly Visable'
))
->add('PrimaryYN', 'choice', array(
'choices' => array( 'false'=>'Secondary', 'true'=>'Primary'),
'required'=>true,
'label'=>'Primary Contact',
))
->add('save', 'submit', array(
'label'=>'Add Address',
'attr'=>array(
'class'=>'btn btn-primary',
),
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Site\UserBundle\Entity\UserAddress',
'csrf_protection'=>false,
));
}
/**
* @return string
*/
public function getName()
{
return 'Create_User_Address';
}
}
控制器功能是:(我正在使用fosrestbundle)
public function newAddressAction($userid, Request $request)
{
$statusCode = 201;
$address = new UserAddress();
$address->setUserId($userid);
$form = $this->createForm( new UserAddressType(), $address, array(
'method'=>'GET',
));
$form->handleRequest($request);
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($address);
$em->flush();
return new Response('User Added to system');
}
return $this->render('SiteUserBundle:UserAddress:newUserAddress.html.twig', array(
'form' => $form->createView(),
)); }
Twig模板非常简单。所有数据都正确发布到服务器:(查询字符串参数)
Create_User_Address[LevelId]:0
Create_User_Address[AddressTypeId]:5
Create_User_Address[AddressData]:555-555-5555
Create_User_Address[PublicYN]:false
Create_User_Address[PrimaryYN]:false
Create_User_Address[save]:
Create_User_Address[UserId]:3
但我一直收到以下错误:
An exception occurred while executing 'INSERT INTO user_address (user_id, level_id, address_type_id, address_data, public_yn, primary_yn) VALUES (?, ?, ?, ?, ?, ?)' with params [null, 0, null, "555-555-5555", "false", "false"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null
如您所见,UserID和AddressTypeId字段未从表单映射到实体。我查看了所有3件以上和ove的代码,对于我的生活,我无法看到不匹配发生的地方。我曾在某一点更改了Entity中这两个字段的名称,但我删除了所有getter和setter并重新生成它们以及清除dev缓存。
我的预感是Symfony2中有一个文件有一个映射类错了,但我找不到它..
全部谢谢
编辑:
我尝试清除这里所述的学说缓存:Symfony2 doctrine clear cache。
app/console doctrine:cache:clear-metadata
app/console doctrine:cache:clear-query
app/console doctrine:cache:clear-result
这会导致生成相同的错误,因此缓存问题可能不在桌面上。
编辑:
根据艾萨克的建议,我删除了->add('UserId', 'hidden')
。表单仍然贴有相同的错误消息。正在为页面正确生成该字段;
<input type="hidden" id="Create_User_Address_UserId" name="Create_User_Address[UserId]" class=" form-control" value="3">
正如您可以从上面的查询参数中看到的那样正确地发回服务器。
编辑:
我将问题跟踪到User
和UserAddressType
变量。如果我删除这两个变量及其getter和setter,则表单可以完美运行而无需对我的代码进行其他修改。我应该注意到这两个变量是与其他实体的连接。他们似乎正在消除表格提交的数据。
答案 0 :(得分:0)
删除
->add('UserId','hidden')
它可能用null覆盖UserId,因为它是隐藏的并且没有值
答案 1 :(得分:0)
根据lsouza的建议,我必须创建一个data transformer。
namespace Site\UserBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Site\UserBundle\Entity\UserAddressType;
class AddressTypeToNumber implements DataTransformerInterface
{
/**
* @var ObjectManager
*/
private $om;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object(val) to a string
*
* @param UserAddressType|null $val
* @return string
*/
public function transform($val)
{
if (null === $val) {
return "";
}
return array();
}
/**
* Transfers a string to an object (UserAddressType)
*
* @param string $val
* @return UserAddressType|null
* @throws TransformationFailedException if object is not found
*/
public function reverseTransform($val)
{
if (!$val) {
return null;
}
$addId = $this->om
->getRepository('SiteUserBundle:UserAddressType')
->findOneBy(array('AddressTypeId' => $val));
if (null === $addId) {
throw new TransformationFailedException(sprintf(
'An Address Type with the ID of "%s" does not exsist in the system',
$val
));
}
return $addId;
}
}
请注意,Transformer
函数当前返回null,但这应返回表单可以使用的值。
其他一些可能对其他人有帮助的注意事项是表单类也需要更改。
setDefaultOptions
函数需要在$resolver
变量中添加以下内容:
->setRequired(array(
'em',
))
->setAllowedTypes(array(
'em'=>'Doctrine\Common\Persistence\ObjectManager',
));
buildForm
函数需要稍微更改才能接受em
选项:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$em = $options['em'];
$transformer = new AddressTypeToNumber($em);
该字段需要更改为包含实体中关系的varrable,而不是链接中使用的字段:
->add(
$builder->create('UserAddressType', 'entity', array(
'class' => 'SiteUserBundle:UserAddressType',
'property' => 'AddressDescription',
'label' => 'Address Type'
))
->addModelTransformer($transformer)
)
最后在您的控制器中,您需要将$this->getDoctrine()->getManager()
的实例传递给表单类:
$form = $this->createForm( new UserAddressType(), $address, array(
'em' => $this->getDoctrine()->getManager(),
));
我希望这有助于其他人。