教义wrapInTransaction 不持久

问题描述 投票:0回答:1

在 PHP8.1 上使用 Doctrine v2.12.2 和 MySQL5.7.38 数据库,尝试使用下面定义的

wrapInTransaction
函数内部的
setValue
方法来持久化数据实体;我的理解是,成功完成
wrapInTransaction
方法后,实体应该存在于数据库中;在调试和单步执行时,
AccountSettingModelImpl
实体对象在字段中填充了所有正确的数据,但从未在数据库中看到该条目。该方法被多次调用以设置数据;但我的假设是,因为它没有被存储,所以当调用
fetchSettingByKey
时,会返回一个错误,然后陷入 Doctrine 尝试再次创建实体并抛出“重复条目”异常的陷阱。

奇怪的是,一些值存储在数据库中,但似乎 php 请求必须成功完成才能发生这种情况。是否有必须启用才能使

wrapInTransaction
立即持续存在的设置?

/**
 * Class SettingModel
 * @package kor\classes\models
 * @Entity @Table(name="korAccountSettings")
 */
class AccountSettingModelImpl extends AbstractBaseModel implements AccountSettingModel
{
    /**
     * @Id
     * @ManyToOne(targetEntity="AccountModelImpl")
     * @JoinColumn(name="asAccountId", referencedColumnName="aId")
     * @var AccountModelImpl
     */
    private AccountModel $account;

    /**
     * @Id
     * @Column(name="asKey", type="text")
     * @var string
     */
    private string $key;

    /**
     * @Column(name="asVal", type="text", nullable=true)
     * @var mixed
     */
    private ?string $val;

    /**
     * @Column(name="asUpdated", type="datetime_immutable")
     * @var DateTime
     */
    private DateTimeInterface $updated;
}
public function setValue(string $sKey, $sVal)
    {
        Application::getEntityManager()->wrapInTransaction(function (EntityManager $entityManager)
        use ($sKey, $sVal) {
            $accountModel = $this->getAccountModel();
            try {
                $settingModel = AccountSettingHelper::fetchSettingByKey($sKey, $accountModel);
                $settingModel->setVal($sVal);
                if(is_null($sVal) && $entityManager->contains($settingModel))
                    $entityManager->remove($settingModel);
            } catch (SettingNotFoundException $e) {
                $settingModel = Application::newEntity(AccountSettingModel::class);
                $settingModel->setAccount($accountModel);
                $settingModel->setKey($sKey);
                $settingModel->setVal($sVal);
                $entityManager->persist($settingModel);
            }
        });
        return $sVal;
    }
An exception occurred while executing a query: Duplicate entry '1-rl.enabled' for key 'PRIMARY'
#0 OR\vendor\doctrine\dbal\src\Connection.php(1814): Doctrine\DBAL\Driver\API\MySQL\ExceptionConverter->convert() 
#1 OR\vendor\doctrine\dbal\src\Connection.php(1749): Doctrine\DBAL\Connection->handleDriverException() 
#2 OR\vendor\doctrine\dbal\src\Statement.php(184): Doctrine\DBAL\Connection->convertExceptionDuringQuery() 
#3 OR\vendor\doctrine\dbal\src\Statement.php(221): Doctrine\DBAL\Statement->execute() 
#4 OR\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php(278): Doctrine\DBAL\Statement->executeStatement() 
#5 OR\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(1129): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts() 
#6 OR\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(426): Doctrine\ORM\UnitOfWork->executeInserts() 
#7 OR\vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php(398): Doctrine\ORM\UnitOfWork->commit() 
#8 OR\vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php(269): Doctrine\ORM\EntityManager->flush()
php mysql doctrine-orm doctrine
1个回答
0
投票

您需要调用

$entityManager->flush()
来触发对数据库的提交。

这可能发生在代码中的其他地方,从而触发您描述的行为。

© www.soinside.com 2019 - 2024. All rights reserved.