使用唯一键更新实体 - 插入而不是更新

got*_*oto 2 symfony doctrine-orm

我的服务中有这个方法:

public function updateCountry($p_entity) {   


    var_dump($p_entity->getId());    //return 3 (as expected)
    var_dump(get_class($p_entity) ); //return Country (as expected)

    $this->em->persist($p_entity);
    $this->em->flush();
}
Run Code Online (Sandbox Code Playgroud)

我叫它

$country = $em->getRepository('blabla')->find(3);
$my_service->updateCountry($country);
Run Code Online (Sandbox Code Playgroud)

但生成的请求是

Doctrine\DBAL\DBALException:执行'INSERT INTO country(code,label,created_at,updated_at)VALUES(?,?,?,?)'时出现异常,其中params ["EN","England","201 3- 08-23 00:00:00",null]:

我有一个独特的学说约束

这是我的country.orm.yml

To\Bundle\Entity\Country:
    type: entity
    table: country
    repositoryClass: To\Bundle\Entity\CountryRepository

    fields:
         id:
             type: integer
             id: true
             generator:
                 strategy: AUTO
         code:
             type: string
             length: 255
             unique: true
             nullable: false
Run Code Online (Sandbox Code Playgroud)

为什么我生成了插入请求而不是更新请求?

Jov*_*vic 6

你能坚持新的实体吗?

如果可以,请尝试合并您的对象:

public function updateCountry($p_entity) {
    var_dump($p_entity->getId());    //return 3 (as expected)
    var_dump(get_class($p_entity) ); //return Country (as expected)

    $this->em->merge($p_entity); // MERGE not PERSIST
    $this->em->flush();
}
Run Code Online (Sandbox Code Playgroud)

来自官方文档:

如果X是新的实体实例,则将创建新的托管副本X',并将X的状态复制到此托管实例上.

所以,基本上,EntityManager::merge可以用来持久保存新创建的对象并合并exutent one ...

  • 合并当然有效但你应该做的是检索现有的国家实体(使用查找),然后更新实体并刷新它.这就是为什么你没有看到合并使用太多.在正常的检索/更新/刷新工作流程中很少需要它. (2认同)