"Class does not exist. Reflection failed." 延迟加载和对象存储

"Class does not exist. Reflection failed." with lazy loading and object storages

我正在将网站从 TYPO3 8 升级到 TYPO3 9

所有代码都适用于 TYPO3 8。
现在我必须做很多调整,因为它来自更早的 TYPO3(TCA,学说,......)并抛出一些错误。

目前我的一些页面有问题我只得到这个错误(稍作修改):

(1/2) #1278450972 TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException

Class VendorName\VendorExtensionName\Domain\Model\TYPO3\CMS\Extbase\Persistence\ObjectStorage does not exist. Reflection failed.

我假设它是由这段代码触发的:

<?php
namespace VendorName\VendorExtensionName\Controller;
use TYPO3\CMS\Extbase\Annotation\Inject;

class AnsprechpartnerController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

    /**
     * ansprechpartnerRepository
     *
     * @Inject
     * @var \VendorName\VendorExtensionName\Domain\Repository\AnsprechpartnerRepository
     */
    protected $ansprechpartnerRepository;

    [...]

    /**
     * action showDetail
     *
     * @return void
     */
    public function showDetailAction() {
        $pids = $this->settings['pids'];
        $this->settings['ansprechpartner'] = explode(',', $this->settings['ansprechpartner']);
        foreach ($this->settings['ansprechpartner'] as $uid) {
            $person = $this->ansprechpartnerRepository->findByUid($uid);  

    [...]

因为最后一行在调试堆栈中。

扩展有8种相互关联的记录。我假设因此定义了关系 lazy 并使用了对象存储。

<?php
namespace VendorName\VendorExtensionName\Domain\Model;
use TYPO3\CMS\Extbase\Annotation\ORM\Lazy;
/**
 *
 * @package vendor_extension_name
 *
 */
class Ansprechpartner extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

[...]


/**
 * Organisationseinheit
 *
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\VendorName\VendorExtensionName\Domain\Model\Organisation>
 * @Lazy
 */
protected $organisationseinheit;

/**
 * Dienstleistungen
 *
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\VendorName\VendorExtensionName\Domain\Model\AnsprechpartnerDienstleistung>
 * @Lazy
 */
protected $dienstleistungen = NULL;

[...]

但是这里混淆的class顺序是颠倒的。
尽管如此,这可能是现有命名空间 VendorName\VendorExtensionName\Domain\Model[\Ansprechpartner] 和
mixing/concatenating 的原因 \TYPO3\CMS\Extbase\Persistence\ObjectStorage 到陌生的 class 名字
VendorName\VendorExtensionName\Domain\Model\TYPO3\CMS\Extbase\Persistence\ObjectStorage,当然不存在


编辑:
插入
的用法 use TYPO3\CMS\Extbase\Annotation\Inject;
use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; 而不是在 injectlazy 中构建,后者没有任何效果。


编辑 2:

存储初始化(上面class的例子):

class Ansprechpartner extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{

    :
    /**
     * __construct
     *
     * @return Ansprechpartner
     */
    public function __construct() {
        $this->initStorageObjects();
    }

    /**
     * Initializes all ObjectStorage properties.
     *
     * @return void
     */
    protected function initStorageObjects() {
        $this->organisationseinheit = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
        $this->dienstleistungen = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
    }
    :

在 9.0 版中,注释 @lazy 被替换为 @TYPO3\CMS\Extbase\Annotation\ORM\Lazy

也许这可以帮助:https://docs.typo3.org/typo3cms/extensions/core/latest/Changelog/9.0/Feature-83078-ReplaceLazyWithTYPO3CMSExtbaseAnnotationORMLazy.html

我们发现,这是由于 9.x 中的更改,现在在注释和类型提示中支持相对命名空间。

在 9.x 之前,Extbase 反射总是假设为绝对名称空间。

如果有一个带有此签名的方法,它在 9.x 之前有效(这是一个错误)并且在 9.x 之后不再有效:

public function setSomeStorage(TYPO3\CMS\Extbase\Persistence\ObjectStorage $storage) {

这必须是:

public function setSomeStorage(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $storage) {

如果您收到一条带有前导括号的错误消息,如下所示:(1/3) 那么在这种情况下搜索页面上的所有三个错误是值得的。
在我的例子中,最后一条消息错误消息提到了语法错误,然后 class 自然不会加载 - 但我可以更正语法错误,然后一切正常。