You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 11:54:03