TYPO3 v9.5 Extbase中如何获取更新中对象的持久化旧版本
问题原因
Extbase 持久化层默认开启了会话级一级缓存,当相同 UID 的对象已经被加载到内存会话中时,后续所有同 UID 的 Repository 查询都会直接返回内存中已有的对象引用,不会重新发起数据库查询。
你控制器方法参数中的 $feedback 是 Extbase 通过 PropertyMapper 基于表单提交的新值映射生成的对象,此时已经被注册到持久化会话中,你再调用 findByUid 拿到的就是同一个更新后的对象,所以两个 var_dump 输出值相同。
解决方法
方法1:清除指定对象的会话缓存(适合需要完整旧对象的场景)
注入 Extbase 持久化管理器,查询旧值前先将已映射的新对象从会话中移除,后续查询就会从数据库拉取原始旧数据:
<?php namespace XX\Xxxxxx\Controller; use XX\Xxxxxx\Domain\Model\Feedback; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Utility\DebuggerUtility; use TYPO3\CMS\Extbase\Annotation\Inject; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; class ContactController extends ActionController { /** * @Inject * @var XX\Xxxxxx\Domain\Repository\FeedbackRepository */ protected $feedbackRepository = null; /** * @Inject * @var PersistenceManager */ protected $persistenceManager = null; public function updateFeedbackAction(Feedback $feedback) { // 将已映射的新对象从持久化会话中移除 $this->persistenceManager->forgetObject($feedback); // 此时查询得到的是数据库中的原始旧对象 $oldFeedback = $this->feedbackRepository->findByUid($feedback->getUid()); DebuggerUtility::var_dump($feedback->getState()); // 输出新值 Test DebuggerUtility::var_dump($oldFeedback->getState()); // 输出旧值 Test... // 后续正常执行更新逻辑即可,不会受forgetObject影响 // $this->feedbackRepository->update($feedback); // $this->persistenceManager->persistAll(); } }
方法2:直接查询原生数据库(适合仅需对比少数字段的场景)
跳过 Extbase ORM 层直接用 Doctrine DBAL 查询数据库原始值,性能更高,也不会影响持久化会话:
public function updateFeedbackAction(Feedback $feedback) { $uid = $feedback->getUid(); // 替换为你实际的模型表名 $tableName = 'tx_xxxxxx_domain_model_feedback'; $connection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( \TYPO3\CMS\Core\Database\ConnectionPool::class )->getConnectionForTable($tableName); $oldState = $connection->fetchOne( "SELECT state FROM {$tableName} WHERE uid = ?", [$uid] ); DebuggerUtility::var_dump($feedback->getState()); // 输出新值 Test DebuggerUtility::var_dump($oldState); // 输出旧值 Test... }
内容的提问来源于stack exchange,提问作者Cold_Class
相关产品推荐
相关产品推荐

