【发布时间】:2018-07-27 15:57:24
【问题描述】:
我在通过表单持久化一个实体时遇到问题。
我的情况是:
在我的索引页面中,我有一个使用 EntityType 检索实体的简单表单。此表单没有数据类,我使用它只是为了保存包含此实体的会话变量,并且我希望它可以通过我的应用程序插入到我的表单中。 这是完整的控制器:
class HomeController extends Controller{
/**
* @Route("/", name="index")
*/
public function index(Request $request) {
$session = $this->get('session');
dump($session->get('empresa'));
$usuario = $this->getUser();
$empresas = $usuario->getEmpresas();
$form = $this->createFormBuilder()
->add('empresa', EntityType::class, [
'class' => Empresa::class,
'choice_label' => 'razaoSocial',
'choice_value' => 'id',
'label' => 'Empresa:',
'choices' => $usuario->getEmpresas()
])
->add('selecionar', SubmitType::class, ['label' => 'Selecionar'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$session->set('empresa', $data['empresa']);
return $this->redirectToRoute('index');
}
return $this->render('home/index.html.twig', ['form' => $form->createView()]);
}
它按预期工作,当页面重新加载时,所有数据都出现在转储中。
现在在另一个控制器中,我有一个表单,它保存了一个与我保存在转储中的实体相关的实体(它是一个 OneToMany 关系)。
public function cadastrarRapido(Request $request){
$usuario = $this->getUser();
$session = $this->get('session');
dump($session->get('empresa'));
$produto = new Produto();
$form = $this->formFactory->create(ProdutoRapidoType::class, $produto);
$form->add('cadastrar', SubmitType::class, ['label' => 'Cadastrar']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()){
$produto = $form->getData();
$empresa = $session->get('empresa');
$produto->setEmpresa($empresa);
$this->entityManager->persist($produto);
$this->entityManager->flush();
$this->flashBag->add('success', 'Produto adicionado!');
return new RedirectResponse($this->router->generate('cadastro_produto_rapido'));
}
return new Response(
$this->twig->render(
'produto/cadastro-rapido.html.twig',
['form' => $form->createView()]
)
);
}
所以,当我尝试提交此表单时,我收到以下错误
A new entity was found through the relationship 'App\Entity\Produto#empresa' that was not configured to cascade persist operations for entity:
App\Entity\Empresa@000000006e7adf9a000000004feede5f.
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
我没有尝试更新我的其他实体,因此不是使用 cascade=persist 的情况。 我要做的就是将外键保存在我试图与保存在会话变量中的对象 ID 的实体中。
我是否在会话变量中以正确的方式捕获对象?如果我使用$session->set('empresa', $data['empresa']->getId());,我会在提交表单时收到此错误
Argument 1 passed to App\Entity\Produto::setEmpresa() must be an instance of App\Entity\Empresa or null, integer given
我想我想做的很简单,但我不知道这是否是正确的方法。感谢您的帮助
【问题讨论】:
-
会话变量中保存的实体与其他实体有很多关系,不知道这是不是这个问题的重要细节..
-
学说中的实体需要由实体管理者“管理”。您不能从会话中拉出一个并尝试关联它。教义会认为它是新的。您需要从经理那里查找 $empresa 或可能使用学说参考。
-
在这种情况下你建议我做什么@Cerad?我需要有一个“全局”实体 $empresa,它将插入到我的应用程序的许多表单中,但用户也应该能够通过表单更改这个全局变量
-
只需从教义数据库中提取 $empresa。如果需要,您仍然可以在会话中存储副本。您可能会认为,因为您最初从数据库中提取并存储了它,所以它可以工作,但不是。 Doctrine 需要您在每个请求中获取所有实体。
-
转到inanzzz.com/index.php/post/hry2/…,向右滚动页面底部并阅读其中的内容。所以你要做的是,在 Produto 文件中将
cascade={"persist"}添加到$empresa属性。