我有两个实体
Room.php
/**
* @ORMTable(name="room")
* @ORMEntity(repositoryClass="AhsioStackBundleRepositoryRoomRepository")
*/
class Room
{
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
// ...
/**
* @ORMOneToMany(targetEntity="AhsioStackBundleEntityWorkstation", mappedBy="room", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $workstations;
和工作站.php
/**
* @ORMTable(name="workstation")
* @ORMEntity(repositoryClass="AhsioStackBundleRepositoryWorkstation")
*/
class Workstation
{
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORMManyToOne(targetEntity="AhsioStackBundleEntityRoom")
* @ORMJoinColumn(name="room_id", referencedColumnName="id", nullable=false)
*/
private $room;
// ...
我添加了一个带有收集字段的房间类型,用于添加/更新/删除工作站
RoomType.php
class RoomType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('id', 'hidden', array(
'read_only' => true,
))
// ....
->add('workstations', 'collection', array(
'type' => new WorkstationType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
// ...
}
工作站类型是一个简单的类型,只有两个字段(id
&number
)。
问题是,当我试图将现有房间(包含id为(1和2)的两个工作站)的RoomType与以下数组(仅包含两个工作站中的一个)绑定时:
array(4) {
["id"]=> string(1) "3"
["workstations"]=> array(1) {
[0]=> array(2) {
["id"]=> int(1)
["number"]=> int(200)
}
}
更新完成得很好,id为2的工作站已删除。但是,当我试图删除给定房间的所有工作站时,使用:
array(4) {
["id"]=> string(1) "3"
["workstations"]=> array(0) {
}
工作站仍然在那里,我所做的绑定执行得很好,以下是我在使用最后一个给定数组绑定$form后执行$form->getData()时得到的结果:
object(AhsioStackBundleEntityRoom)#229 (4) {
["id":protected]=> string(1) "3"
["name":protected]=> string(20) "first room (updated)"
["description":protected]=> string(39) "This first room is an old one (updated)"
["workstations":protected]=> array(0) {
}
}
因此,更新后的房间没有工作站。有人能告诉我,当我保留最后一个绑定的房间时,为什么我的工作站没有被删除吗?
这是我的控制器代码的一部分,我正在使用它来测试更新。。。
// The Room $id is given ...
$roomArray = array(
'id' => $id,
'name' => 'first room (updated)',
'description' => 'This first room is an old one (updated)',
'workstations' => array(),
);
$form = $this->createForm(new RoomType(), $room);
$form->bind($roomArray);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($room);
$em->flush();
}
我认为接收workstations
数组的setter永远不会被调用,因为数组是空的。
尝试通过添加跟踪来查看是否调用了它。
此外,您应该在工作站映射中添加cascade="merge"选项。
我认为在尝试更新和删除实体/相关实体时不应该调用persist
。
你可能应该试着打电话给:
$em->merge($room);
在与表单数据绑定之前。这样,您将从数据库中恢复数据,剩下的工作由orphanRemoval
完成
另外,你不应该用Request
而不是用数据对象来bind
你的表单吗?