我有一个内部有链接实体的symfony实体。我无法使UniqueEntity正常工作。
当我在此处运行表单时,除了唯一的Assert之外,所有Assert都正常工作。它完全忽略了它。如果我从UniqueEntity中删除雇主字段,那么它可以工作。然而,这不是我需要的。我需要一个具有两者组合的唯一实体,如您在UniqueConstraints中所见。
为了澄清,我得到的错误是四个字段中每个字段的重复输入错误500(异常),而不是没有错误500的错误重复错误。
Employee.php($雇主是第二个实体)
<?php
namespace TechE\DashboardBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Type;
use libphonenumber\PhoneNumber;
use Misd\PhoneNumberBundle\Validator\Constraints\PhoneNumber as AssertPhoneNumber;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Employee
*
* @ORM\Table(name="employee", uniqueConstraints={@ORM\UniqueConstraint(name="EMPLOYEE_SSN", columns={"EMPLOYEE_SSN", "EMPLOYER_ID"}), @ORM\UniqueConstraint(name="EMPLOYEE_EMAIL", columns={"EMPLOYEE_EMAIL", "EMPLOYER_ID"})}, indexes={@ORM\Index(name="EMPLOYER_ID", columns={"EMPLOYER_ID"})})
* @UniqueEntity(fields={"employer","employeeEmail"},errorPath="employeeEmail", message="This email is already in use.")
* @UniqueEntity(fields={"employer","employeeClockPin"},errorPath="employeeClockPin", message="This pin is already in use.")
* @UniqueEntity(fields={"employer","employeeSsn"},errorPath="employeeSsn", message="This ssn is already in use.")
* @ORM\Entity
*/
class Employee {
/**
* @var integer
*
* @ORM\Column(name="EMPLOYEE_ID", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $employeeId;
/**
* @var \DateTime
*
* @ORM\Column(name="MODIFIED_TIME", type="datetime", nullable=false)
*/
private $modifiedTime;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_EMAIL", type="string", length=255, nullable=false)
* @Assert\NotBlank()
* @Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true,
* checkHost = true
* )
*/
private $employeeEmail;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_PASSWORD", type="string", length=255, nullable=false)
* @Assert\Length(min = "3", max ="25", minMessage = "Must be at least {{ limit }} characters length",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
* @Assert\NotBlank()
*/
private $employeePassword;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_CLOCK_PIN", type="string", length=7, nullable=false)
* @Assert\Length(min = "3", max ="7", minMessage = "Must be at least {{ limit }} characters length",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
* @Assert\NotBlank()
*/
private $employeeClockPin;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_FIRST", type="string", length=255, nullable=false)
* @Assert\Length(min = "3", max ="255", minMessage = "Must be at least {{ limit }} characters length",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
* @Assert\NotBlank()
*/
private $employeeFirst;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_LAST", type="string", length=255, nullable=false)
* @Assert\Length(min = "3", max ="255", minMessage = "Must be at least {{ limit }} characters length",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
* @Assert\NotBlank()
*/
private $employeeLast;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_MIDDLE", type="string", length=1, nullable=true)
* @Assert\Length(max ="1",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
*/
private $employeeMiddle;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_NICKNAME", type="string", length=255, nullable=true)
* @Assert\Length(max ="255",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
*/
private $employeeNickname;
/**
* @var PhoneNumber
* @Type("libphonenumber\PhoneNumber")
* @ORM\Column(name="EMPLOYEE_PRIMARY_PHONE", type="phone_number", length=35, nullable=false)
* @AssertPhoneNumber(defaultRegion="US")
* @Assert\Length(max ="35")
* @Assert\NotBlank()
*/
private $employeePrimaryPhone;
/**
* @var PhoneNumber
* @Type("libphonenumber\PhoneNumber")
* @ORM\Column(name="EMPLOYEE_SECONDARY_PHONE", type="phone_number", length=35, nullable=true)
* @AssertPhoneNumber(defaultRegion="US")
*/
private $employeeSecondaryPhone;
/**
* @var PhoneNumber
* @Type("libphonenumber\PhoneNumber")
* @ORM\Column(name="EMPLOYEE_TEXT_CAPABLE_PHONE", type="phone_number", length=35, nullable=true)
* @AssertPhoneNumber(defaultRegion="US")
*/
private $employeeTextCapablePhone;
/**
* @var string
*
* @ORM\Column(name="EMPLOYEE_SSN", type="string", length=255, nullable=false)
* @Assert\Length(min = "9", max ="50", minMessage = "Must be at least {{ limit }} characters length",
* maxMessage = "Cannot be longer than {{ limit }} characters length")
* @Assert\NotBlank()
*/
private $employeeSsn;
/**
* @var \TechE\DashboardBundle\Entity\Employer
*
* @ORM\ManyToOne(targetEntity="TechE\DashboardBundle\Entity\Employer")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="EMPLOYER_ID", referencedColumnName="EMPLOYER_ID")
* })
*/
private $employer;
/**
* @var boolean
*
* @ORM\Column(name="EMPLOYEE_SUSPENDED", type="boolean", length=1, nullable=false)
*/
private $employeeSuspended = 0;
/**
* @var string
* @ORM\Column(name="EMPLOYEE_SEX", type="string", length=1, nullable=false)
* @Assert\Choice(
* choices = { "m", "f" },
* message = "Choose a valid gender.")
*/
private $employeeSex;
/**
* Get employeeId
*
* @return integer
*/
public function getEmployeeId() {
return $this -> employeeId;
}
/**
* Set modifiedTime
*
* @param \DateTime $modifiedTime
* @return Employee
*/
public function setModifiedTime($modifiedTime) {
$this -> modifiedTime = $modifiedTime;
return $this;
}
/**
* Get modifiedTime
*
* @return \DateTime
*/
public function getModifiedTime() {
return $this -> modifiedTime;
}
/**
* Set employeeEmail
*
* @param string $employeeEmail
* @return Employee
*/
public function setEmployeeEmail($employeeEmail) {
$this -> employeeEmail = $employeeEmail;
return $this;
}
/**
* Get employeeEmail
*
* @return string
*/
public function getEmployeeEmail() {
return $this -> employeeEmail;
}
/**
* Set employeePassword
*
* @param string $employeePassword
* @return Employee
*/
public function setEmployeePassword($employeePassword) {
$this -> employeePassword = $employeePassword;
return $this;
}
/**
* Get employeePassword
*
* @return string
*/
public function getEmployeePassword() {
return $this -> employeePassword;
}
/**
* Set employeeClockPin
*
* @param string $employeeClockPin
* @return Employee
*/
public function setEmployeeClockPin($employeeClockPin) {
$this -> employeeClockPin = $employeeClockPin;
return $this;
}
/**
* Get employeeClockPin
*
* @return string
*/
public function getEmployeeClockPin() {
return $this -> employeeClockPin;
}
/**
* Set employeeFirst
*
* @param string $employeeFirst
* @return Employee
*/
public function setEmployeeFirst($employeeFirst) {
$this -> employeeFirst = $employeeFirst;
return $this;
}
/**
* Get employeeFirst
*
* @return string
*/
public function getEmployeeFirst() {
return $this -> employeeFirst;
}
/**
* Set employeeLast
*
* @param string $employeeLast
* @return Employee
*/
public function setEmployeeLast($employeeLast) {
$this -> employeeLast = $employeeLast;
return $this;
}
/**
* Get employeeLast
*
* @return string
*/
public function getEmployeeLast() {
return $this -> employeeLast;
}
/**
* Set employeeMiddle
*
* @param string $employeeMiddle
* @return Employee
*/
public function setEmployeeMiddle($employeeMiddle) {
$this -> employeeMiddle = $employeeMiddle;
return $this;
}
/**
* Get employeeMiddle
*
* @return string
*/
public function getEmployeeMiddle() {
return $this -> employeeMiddle;
}
/**
* Set employeeNickname
*
* @param string $employeeNickname
* @return Employee
*/
public function setEmployeeNickname($employeeNickname) {
$this -> employeeNickname = $employeeNickname;
return $this;
}
/**
* Get employeeNickname
*
* @return string
*/
public function getEmployeeNickname() {
return $this -> employeeNickname;
}
/**
* Set employeePrimaryPhone
*
* @param PhoneNumber $employeePrimaryPhone
* @return Employee
*/
public function setEmployeePrimaryPhone($employeePrimaryPhone) {
$this -> employeePrimaryPhone = $employeePrimaryPhone;
return $this;
}
/**
* Get employeePrimaryPhone
*
* @return PhoneNumber
*/
public function getEmployeePrimaryPhone() {
return $this -> employeePrimaryPhone;
}
/**
* Set employeeSecondaryPhone
*
* @param PhoneNumber $employeeSecondaryPhone
* @return Employee
*/
public function setEmployeeSecondaryPhone($employeeSecondaryPhone) {
$this -> employeeSecondaryPhone = $employeeSecondaryPhone;
return $this;
}
/**
* Get employeeSecondaryPhone
*
* @return PhoneNumber
*/
public function getEmployeeSecondaryPhone() {
return $this -> employeeSecondaryPhone;
}
/**
* Set employeeTextCapablePhone
*
* @param PhoneNumber $employeeTextCapablePhone
* @return Employee
*/
public function setEmployeeTextCapablePhone($employeeTextCapablePhone) {
$this -> employeeTextCapablePhone = $employeeTextCapablePhone;
return $this;
}
/**
* Get employeeTextCapablePhone
*
* @return PhoneNumber
*/
public function getEmployeeTextCapablePhone() {
return $this -> employeeTextCapablePhone;
}
/**
* Set employeeSsn
*
* @param string $employeeSsn
* @return Employee
*/
public function setEmployeeSsn($employeeSsn) {
$this -> employeeSsn = $employeeSsn;
return $this;
}
/**
* Get employeeSsn
*
* @return string
*/
public function getEmployeeSsn() {
return $this -> employeeSsn;
}
/**
* Set employer
*
* @param \TechE\DashboardBundle\Entity\Employer $employer
* @return Employee
*/
public function setEmployer(\TechE\DashboardBundle\Entity\Employer $employer = null) {
$this -> employer = $employer;
return $this;
}
/**
* Get employer
*
* @return \TechE\DashboardBundle\Entity\Employer $employer
*/
public function getEmployer() {
return $this -> employer;
}
/**
* Get employeeSuspended
*
* @return boolean
*/
public function isEmployeeSuspended() {
return $this -> employeeSuspended;
}
/**
* Set employeeSuspended
*
* @param string $employeeSuspended
* @return Employee
*/
public function setEmployeeSuspended($employeeSuspended = 0) {
$this -> employeeSuspended = $employeeSuspended;
return $this;
}
/**
* Set employeeSex
*
* @param string $employeeSex
* @return Employee
*/
public function setEmployeeSex($employeeSex) {
$this -> employeeSex = $employeeSex;
return $this;
}
/**
* Get employeeSex
*
* @return string
*/
public function getEmployeeSex() {
return $this -> employeeSex;
}
}
Employer.php
<?php
namespace TechE\DashboardBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Employer
*
* @ORM\Table(name="employer", uniqueConstraints={@ORM\UniqueConstraint(name="EMPLOYER_SUBDOMAIN", columns={"EMPLOYER_SUBDOMAIN"})})
* @ORM\Entity
*/
class Employer
{
/**
* @var integer
*
* @ORM\Column(name="EMPLOYER_ID", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $employerId;
/**
* @var \DateTime
*
* @ORM\Column(name="MODIFIED_TIME", type="datetime", nullable=false)
*/
private $modifiedTime;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_NAME", type="string", length=255, nullable=false)
*/
private $employerName;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_BILLING", type="text", nullable=false)
*/
private $employerBilling;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_BILLING_2", type="string", length=255, nullable=false)
*/
private $employerBilling2;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_BILLING_CITY", type="string", length=255, nullable=false)
*/
private $employerBillingCity;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_BILLING_STATE", type="string", length=255, nullable=false)
*/
private $employerBillingState;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_BILLING_ZIP", type="string", length=255, nullable=false)
*/
private $employerBillingZip;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_COMPANY_NAME", type="string", length=255, nullable=false)
*/
private $employerCompanyName;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_MONTHLY", type="string", length=255, nullable=false)
*/
private $employerMonthly;
/**
* @var boolean
*
* @ORM\Column(name="EMPLOYER_SUSPENDED", type="boolean", nullable=false)
*/
private $employerSuspended;
/**
* @var string
*
* @ORM\Column(name="EMPLOYER_SUBDOMAIN", type="string", length=255, nullable=true)
*/
private $employerSubdomain;
/**
* Get employerId
*
* @return integer
*/
public function getEmployerId()
{
return $this->employerId;
}
/**
* Set modifiedTime
*
* @param \DateTime $modifiedTime
* @return Employer
*/
public function setModifiedTime($modifiedTime)
{
$this->modifiedTime = $modifiedTime;
return $this;
}
/**
* Get modifiedTime
*
* @return \DateTime
*/
public function getModifiedTime()
{
return $this->modifiedTime;
}
/**
* Set employerName
*
* @param string $employerName
* @return Employer
*/
public function setEmployerName($employerName)
{
$this->employerName = $employerName;
return $this;
}
/**
* Get employerName
*
* @return string
*/
public function getEmployerName()
{
return $this->employerName;
}
/**
* Set employerBilling
*
* @param string $employerBilling
* @return Employer
*/
public function setEmployerBilling($employerBilling)
{
$this->employerBilling = $employerBilling;
return $this;
}
/**
* Get employerBilling
*
* @return string
*/
public function getEmployerBilling()
{
return $this->employerBilling;
}
/**
* Set employerBilling2
*
* @param string $employerBilling2
* @return Employer
*/
public function setEmployerBilling2($employerBilling2)
{
$this->employerBilling2 = $employerBilling2;
return $this;
}
/**
* Get employerBilling2
*
* @return string
*/
public function getEmployerBilling2()
{
return $this->employerBilling2;
}
/**
* Set employerBillingCity
*
* @param string $employerBillingCity
* @return Employer
*/
public function setEmployerBillingCity($employerBillingCity)
{
$this->employerBillingCity = $employerBillingCity;
return $this;
}
/**
* Get employerBillingCity
*
* @return string
*/
public function getEmployerBillingCity()
{
return $this->employerBillingCity;
}
/**
* Set employerBillingState
*
* @param string $employerBillingState
* @return Employer
*/
public function setEmployerBillingState($employerBillingState)
{
$this->employerBillingState = $employerBillingState;
return $this;
}
/**
* Get employerBillingState
*
* @return string
*/
public function getEmployerBillingState()
{
return $this->employerBillingState;
}
/**
* Set employerBillingZip
*
* @param string $employerBillingZip
* @return Employer
*/
public function setEmployerBillingZip($employerBillingZip)
{
$this->employerBillingZip = $employerBillingZip;
return $this;
}
/**
* Get employerBillingZip
*
* @return string
*/
public function getEmployerBillingZip()
{
return $this->employerBillingZip;
}
/**
* Set employerCompanyName
*
* @param string $employerCompanyName
* @return Employer
*/
public function setEmployerCompanyName($employerCompanyName)
{
$this->employerCompanyName = $employerCompanyName;
return $this;
}
/**
* Get employerCompanyName
*
* @return string
*/
public function getEmployerCompanyName()
{
return $this->employerCompanyName;
}
/**
* Set employerMonthly
*
* @param string $employerMonthly
* @return Employer
*/
public function setEmployerMonthly($employerMonthly)
{
$this->employerMonthly = $employerMonthly;
return $this;
}
/**
* Get employerMonthly
*
* @return string
*/
public function getEmployerMonthly()
{
return $this->employerMonthly;
}
/**
* Set employerSuspended
*
* @param boolean $employerSuspended
* @return Employer
*/
public function setEmployerSuspended($employerSuspended)
{
$this->employerSuspended = $employerSuspended;
return $this;
}
/**
* Get employerSuspended
*
* @return boolean
*/
public function getEmployerSuspended()
{
return $this->employerSuspended;
}
/**
* Set employerSubdomain
*
* @param string $employerSubdomain
* @return Employer
*/
public function setEmployerSubdomain($employerSubdomain)
{
$this->employerSubdomain = $employerSubdomain;
return $this;
}
/**
* Get employerSubdomain
*
* @return string
*/
public function getEmployerSubdomain()
{
return $this->employerSubdomain;
}
}
EmployeeType.php
<?php
// src/TechE/DashboardBundle/Form/EmployeeType.php
namespace TechE\DashboardBundle\Form;
use libphonenumber\PhoneNumberFormat;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EmployeeType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder -> add('employeeEmail');
$builder -> add('employeePassword', 'password', array('attr' => array(
'min' => '3',
'max' => '25',
'pattern' => '.{3,25}'
)));
$builder -> add('employeeClockPin', 'password', array('attr' => array(
'min' => '3',
'max' => '7',
'pattern' => '.{3,7}'
)));
$builder -> add('employeeFirst', null, array('attr' => array(
'min' => '3',
'max' => '255',
'pattern' => '.{3,255}'
)));
$builder -> add('employeeMiddle');
$builder -> add('employeeLast', null, array('attr' => array(
'min' => '3',
'max' => '255',
'pattern' => '.{3,255}'
)));
$builder -> add('employeeNickname');
$builder -> add('employeePrimaryPhone', 'tel');
$builder -> add('employeeSecondaryPhone', 'tel', array('required' => false));
$builder -> add('employeeTextCapablePhone', 'tel', array('required' => false));
$builder -> add('employeeSsn', null, array('attr' => array(
'min' => '9',
'max' => '50',
'pattern' => '.{9,50}'
)));
$builder -> add('employeeSex', 'choice', array(
'choices' => array(
'm' => 'Male',
'f' => 'Female'
),
'empty_value' => 'Choose a gender',
));
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver -> setDefaults(array(
'data_class' => 'TechE\DashboardBundle\Entity\Employee',
'cascade_validation' => true,
));
}
/**
* @return string
*/
public function getName() {
return 'teche_dashboardbundle_employee';
}
}
控制器操作
public function employee_addAction(Request $request) {
$this -> initialize('Add Employee') -> employeeTab() -> addToBreadcrumb('TechEDashboardBundle_employee_add', 'Add Employee', '', true);
$this -> parameters['group']['children']['TechEDashboardBundle_employee']['breadcrumb'] = true;
$employee = new Employee();
$form = $this -> createForm(new EmployeeType(), $employee);
$data = $form -> getData();
$form -> handleRequest($request);
if ($form -> isValid()) {
$em = $this -> getDoctrine() -> getManager();
$data = $form -> getData();
$employer = $this -> getCurrentEmployer();
$data -> setEmployer($employer);
$em -> persist($data);
$em -> flush();
return $this -> redirect($this -> generateUrl('TechEDashboardBundle_employee_email', array('email' => $data -> getEmployeeEmail())));
}
$this -> parameters['form'] = $form -> createView();
return $this -> render('TechEDashboardBundle:Page:Employee/add.html.twig', $this -> getParameter());
}
更新:我查看了插入时运行的查询。在插入之前只运行了一个额外的查询(当然失败了)。
SELECT t0.EMPLOYER_ID AS EMPLOYER_ID1, t0.MODIFIED_TIME AS MODIFIED_TIME2, t0.EMPLOYER_NAME AS EMPLOYER_NAME3, t0.EMPLOYER_BILLING AS EMPLOYER_BILLING4, t0.EMPLOYER_BILLING_2 AS EMPLOYER_BILLING_25, t0.EMPLOYER_BILLING_CITY AS EMPLOYER_BILLING_CITY6, t0.EMPLOYER_BILLING_STATE AS EMPLOYER_BILLING_STATE7, t0.EMPLOYER_BILLING_ZIP AS EMPLOYER_BILLING_ZIP8, t0.EMPLOYER_COMPANY_NAME AS EMPLOYER_COMPANY_NAME9, t0.EMPLOYER_MONTHLY AS EMPLOYER_MONTHLY10, t0.EMPLOYER_SUSPENDED AS EMPLOYER_SUSPENDED11, t0.EMPLOYER_SUBDOMAIN AS EMPLOYER_SUBDOMAIN12 FROM employer t0 WHERE t0.EMPLOYER_ID = 1
看起来不是检查EMPLOYEE_EMAIL和EMPLOYER_ID唯一性的正确查询。
更新2:我完全了解完整性错误的try catch异常。我不想这样做,因为表演说它很恶心。另外,它需要我搜索异常消息,看看哪个列给我一个完整性错误。并且它一次只能处理一列,这使得在不满足所有3个约束的情况下非常烦人。
答案 0 :(得分:0)
好的,似乎我从未真正将雇主变量设置为它所需要的。
以下解决了这个问题。注意:
$employer = $this -> getCurrentEmployer();
$employee -> setEmployer($employer);
新方法:
public function employee_addAction(Request $request) {
$this -> initialize('Add Employee') -> employeeTab() -> addToBreadcrumb('TechEDashboardBundle_employee_add', 'Add Employee', '', true);
$this -> parameters['group']['children']['TechEDashboardBundle_employee']['breadcrumb'] = true;
$employee = new Employee();
$employer = $this -> getCurrentEmployer();
$employee -> setEmployer($employer);
$form = $this -> createForm(new EmployeeType(), $employee);
$form -> handleRequest($request);
if ($form -> isValid()) {
$em = $this -> getDoctrine() -> getManager();
$data = $form -> getData();
$data -> setEmployer($employer);
$em -> persist($data);
$em -> flush();
return $this -> redirect($this -> generateUrl('TechEDashboardBundle_employee_email', array('email' => $data -> getEmployeeEmail())));
}
$this -> parameters['form'] = $form -> createView();
return $this -> render('TechEDashboardBundle:Page:Employee/add.html.twig', $this -> getParameter());
}