Symfony3 错误与 ManyToMany 与属性



尝试在 2 个表中创建关系时出现错误,如下所示

骆驼 -||--|<- 拉玛达德里瓦达 ->|--||- 女神异闻录

我们正试图创建一个只有一个创建表单,其中包含"LlamadaDerivada"。

拉玛达实体内部

<?php
namespace xxxxBundleEntity;
use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsArrayCollection;
class Llamada {
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="SEQUENCE")
* @ORMSequenceGenerator(sequenceName="llamada_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string
* @AssertLength(
*      max = 50,
*      maxMessage = "Your first name cannot be longer than {{ limit }} characters",
* )
* @ORMColumn(name="nombre", type="string", length=150, nullable=false)
*/
private $nombre;
/**
*
* @ORMOneToMany(targetEntity="LlamadaDerivado", mappedBy="llamada")
*/
private $derivados;
function __construct() {
$this->derivados = new ArrayCollection();
}
function getId() {
return $this->id;
}
function getNombre() {
return $this->nombre;
}
function setId($id) {
$this->id = $id;
}
function setNombre($nombre) {
$this->nombre = $nombre;
}
function getDerivados(){
return $this->derivados;
}
function setDerivados($derivados){
$this->derivados = $derivados;
}
}

然后在LlamadaDerivado实体中,我们有这个

<?php
namespace xxxBundleEntity;
use DoctrineORMMapping as ORM;
/**
* LlamadaDerivado
*
* @ORMTable(name="llamada_derivado")
* @ORMEntity
*/
class LlamadaDerivado
{   
/**
* @var AgendaBundleEntityLlamada
*
* @ORMManyToOne(targetEntity="AgendaBundleEntityLlamada",inversedBy="derivados",cascade={"persist"})
* @ORMId
* @ORMJoinColumns({
*   @ORMJoinColumn(name="id_llamada", referencedColumnName="id")
* })
*/
private $llamada;
/**
* @var AgendaBundleEntityPersonaDerivado
*
* @ORMManyToOne(targetEntity="AgendaBundleEntityPersonaDerivado",inversedBy="llamadas",cascade={"persist"})
* @ORMId
* @ORMJoinColumns({
*   @ORMJoinColumn(name="id_derivado", referencedColumnName="id")
* })
*/
private $derivado;

/**
* @var DateTime
*
* @ORMColumn(name="fecha_derivacion", type="date", nullable=false)
*/
private $fechaDerivacion;

function getLlamada(){
return $this->llamada;
}
function getDerivado(){
return $this->derivado;
}
function getFechaDerivacion() {
return $this->fechaDerivacion;
}
function setLlamada( $llamada) {
$this->llamada = $llamada;
}
function setDerivado( $derivado) {
$this->derivado = $derivado;
}
function setFechaDerivacion($fechaDerivacion) {
$this->fechaDerivacion = $fechaDerivacion;
}
}

在PersonaDerivado实体内部

<?php
namespace xxxBundleEntity;
use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsArrayCollection;
/**
* ReunionLugar
*
* @ORMTable(name="persona_derivado")
* @ORMEntity
*/
class PersonaDerivado
{   
public function __construct() {
$this->llamadas = new ArrayCollection();
}
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="SEQUENCE")
* @ORMSequenceGenerator(sequenceName="reunion_lugar_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="nombre", type="string", length=150, nullable=false)
*/
private $nombre;
/**
* @ORMOneToMany(targetEntity="LlamadaDerivado", mappedBy="derivado")
*/
private $llamadas;
function getId() {
return $this->id;
}
function getNombre() {
return $this->nombre;
}
function setId($id) {
$this->id = $id;
}
function setNombre($nombre) {
$this->nombre = $nombre;
}
function setLlamadas($llamadas) {
$this->llamadas = $llamadas;
}
}

而骆驼类型是

class LlamadaDto extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$disabled = $options['disabled'];

$builder
->add('id', HiddenType::class)
->add('nombre', TextType::class, array(
'disabled' => $disabled,
'attr' => ['maxlength'=>'50']
))->add('apellido', TextType::class, array(
'disabled' => $disabled,
'attr' => ['maxlength'=>'50']
))->add('fecha', DateType::class, array(
'format' => 'dd/MM/yyyy',
'disabled' => $disabled,
'widget' => 'single_text',
'attr' => ['class' => 'datepicker']
))->add('hora', TimeType::class, array(
'disabled' => $disabled
))->add('motivo', TextareaType::class, array(
'disabled' => $disabled,
'attr' => ['maxlength'=>'400']
))->add('telefonoContacto', TextType::class, array(
'disabled' => $disabled,
'attr' => ['maxlength'=>'9']
))->add('derivados', EntityType::class, array(
'class' => 'AgendaBundle:PersonaDerivado',
'choice_label' => 'apellidoNombre',
'placeholder' => 'Seleccionar un derivado',
'multiple' => true,
));
}
public function configureOptions(OptionsResolver$resolver) {
$resolver->setDefaults(array('data_class' => Llamada::class));
}
}

在控制器内部,我们有此代码

<?php
/**
* @Route("/Llamada/save",name="saveLlamada")
*/
public function saveLlamadaAction(Request $request) {
$llamadaService = $this->get('llamadaService');
$derivadoService = $this->get('derivadoService');
$form = $this->createForm(LlamadaDto::class);
$form->handleRequest($request);
$editar = TRUE;
$llamada = $form->getData();
$derivados = $request->request->get("llamada_dto")["derivados"];

$derivadosActuales = $derivadoService->getLlamadaDerivados($llamada->getId());
foreach ($derivados as $key1 => $d) {
foreach ($derivadosActuales as $key2 => $da) {
if($da->getDerivado()->getId()==$d){
array_splice($derivados, array_search($d, $derivados),1);
}
}
}
if ($llamadaService->saveLlamada($llamada)) {
$this->addFlash(
'exitoLlamada', 'Datos de llamada guardados exitosamente'
);
$derivadoService->saveDerivados($derivados,$llamada);
} else {
$this->addFlash(
'errorLlamada', 'Disculpe, hubo un error en el registro de la llamada'
);
}
return new RedirectResponse($this->generateUrl('listaLlamadas', array(), UrlGeneratorInterface::RELATIVE_PATH));
}

调用的服务是这样的:

public function saveLlamada($llamada ){
try{
if($llamada->getId()){
$this->em->merge($llamada);
}else{
$this->em->persist($llamada);
}
$this->em->flush();
return TRUE;
} catch (Exception $ex){
return FALSE;
}
}
public function saveDerivados($derivados,$llamada){
foreach ($derivados as $key => $derivado) {
$llamadaDerivado = new LlamadaDerivado();
$personaLlamada = $this->getDerivado($derivado);
$llamadaDerivado->setLlamada($llamada);
$llamadaDerivado->setDerivado($personaLlamada);
$llamadaDerivado->setFechaDerivacion(new DateTime('now', (new DateTimeZone('America/Argentina/Ushuaia'))));
$this->em->persist($llamadaDerivado);
$this->em->flush();
}
}

这是我们得到的错误:

未捕获的 PHP Exception Doctrine\ORM\ORMInvalidArgumentException: "关联字段 "xxxBundle\Entity\

Llamada#$derivados" 的 "Doctrine\Common\Collections\Collection|array" 类型的预期值,改为 "xxxBundle\Entity\PersonaDerivado" at project\vendor\doctrine\orm\orm\orm\ORMInvalidArgumentException.php 第 206 行

我们已经有 1 周了。 提前非常感谢

您可以尝试在表单类型中使用 CollectionType 而不是 EntityType,尽管我面前有一段代码可以很好地与 EntityType 和 OneToMany 关系的multiple标志配合使用。

看看Llamada实体,$derivados是LlamadaDerivado的数组集合,在你的LlamadaType中,你把它变成实体AgendaBundle的类型:PersonaDerivado,这就是你得到这个错误的原因。考虑使用集合类型每次添加所有对象 LlamadaDerivado 以很好地尊重映射。

相关内容

  • 没有找到相关文章