2015-01-05 50 views
0

我试图保存一个实体,可能或可能不存在,可能或可能不会有一个或两个关系(代码如下)。我目前的方法会导致错误,我很确定我可以自己提出一些解决方法/黑客攻击,但我对正确的“官方”方式感兴趣。学说2保存实体与可能的关系

我现在想:

$entity = new myEntity(); 
if (!empty($id)) 
{ 
    $entity->setId($id); 
} 
$entity->setLocationId($relation_id); //may or may not be null, if not null it's always an already existing location entry in a different table, i.e. not a new 
$entity = $entity_manager->merge($entity); 
$entity_manager->flush(); 

目前主义抱怨位置是一个新的实体,没有ID和政策不允许自动生成的ID。策略确实是这样的,但我根本不添加Location实体,我使用setLocationId()自动生成的方法来添加精确地存在的位置ID,所以我有点困惑。

编辑:当位置标识符不为空而是一个真实的,存在的(以db为单位)位置的id时,我得到了doctrine错误。

和模型:

Location: 
    type: entity 
    table: locationstable 
    id: 
     my-id-column: 
      type: string 
    fields: 
     some fields 
    oneToMany: 
     myEntities: 
      targetEntity: myEntity 
      mappedBy: location 
      cascade: ["persist", "merge"] 

回答

1

如果你打算使用Doctrine 2的ORM那么你真的需要使用它按设计。这意味着使用对象而不是ID。如果你不熟悉这种方法,那么切换到某种有效的记录实现。

//For your case, start by seeing if there is an existing entity: 
// This eliminates all the merge nonsense 
$entity = $entityManager->getRepository('EntityClassName')->find($entityId); 
if (!$entity) 
{ 
    $entity = new Entity(); 

    /* Only do this is you are not autogenerating id's 
    * However, it does raise the question of how you know what the id should be if the entity 
    * if the entity does not yet exist? 
    */ 
    $entity->setId($id); 

    // Persist the new entity 
    $entityManager->persist($entity); 
} 

// Now get a reference to the location object which saves loading the entire location 
// which optimizes things a tiny (probably unnoticeable) bit 
$location = $entityManager->getReference('LocationClassName',$locationId); 
$entity->setLocation($location); 

// And flush changes 
$entityManager->flush(); 

再次,如果你觉得这太复杂或使用了过多的查询,那么就不要使用原则2.您将不断战斗吧。实际上,第二条原则表现得相当好。没有必要担心微观优化。

+0

谢谢,getReference()可能正是我所需要的!另外感谢合并废话的提示:)使用原则2是所有这个问题。我只需要知道什么不是什么。至于ID,我知道应该是什么ID,因为我生成了它们。 – Sejanus

0

试图找到位置记录,并添加到实体:

$entity = new myEntity(); 
if (!empty($id)) 
{ 
    $entity->setId($id); 
} 
//$entity->setLocationId($relation_id); //may or may not be null, if not null it's always an already existing 

$location = $locationRepository->find($relation_id); 
$entity->setLocation($location); 

location entry in a different table, i.e. not a new 
$entity = $entity_manager->merge($entity); 
$entity_manager->flush(); 
+0

这可能会工作,但这是对数据库至少两个查询进行简单的保存操作,是不是有更好的方法? – Sejanus

+0

使用'cascade'操作管理您的问题可能会更加昂贵:请查看[此文档](http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#传递持久性级联操作)。顺便说一下,我的选择是通过表ID找到,它不需要更多的时间 – Matteo