我正在尝试保存可能已存在或可能不存在的实体,可能有也可能没有一个或两个关系(下面的代码)。我当前的方法导致错误,我很确定我可以自己提出一些变通方法/黑客攻击,但我对正确的“官方”方式感兴趣。
我现在正在尝试:
$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();
目前,Doctrine抱怨Location是一个没有ID的新实体,该策略不允许自动生成ID。策略确实如此,但我根本不添加Location实体,我使用setLocationId()自动生成的方法,它精确地添加了现有的Location ID,所以我有点不解。
编辑:当location id不为null但是真实的,现有的(在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"]
答案 0 :(得分: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();
同样,如果你觉得这太复杂或者使用了太多的查询,那就不要使用Doctrine 2.你将不断地与它斗争。在实践中,Doctrine 2的表现相当不错。不需要担心微观优化。
答案 1 :(得分: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();