Skip to content
Advertisement

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

I’m upgrading a website from TYPO3 8 to TYPO3 9

All the code was working well with TYPO3 8.
Now I have to adapt a lot as it came from even earlier TYPO3 (TCA, doctrine, …) and throws some errors.

At the moment I have the problem for some pages I only get this error (in slight modifications):

(1/2) #1278450972 TYPO3CMSExtbaseReflectionExceptionUnknownClassException

Class VendorNameVendorExtensionNameDomainModelTYPO3CMSExtbasePersistenceObjectStorage does not exist. Reflection failed.

I assume it is triggered by this code:

<?php
namespace VendorNameVendorExtensionNameController;
use TYPO3CMSExtbaseAnnotationInject;

class AnsprechpartnerController extends TYPO3CMSExtbaseMvcControllerActionController {

    /**
     * ansprechpartnerRepository
     *
     * @Inject
     * @var VendorNameVendorExtensionNameDomainRepositoryAnsprechpartnerRepository
     */
    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);  

    [...]

as this last line is in the debug stack.

The extension has 8 kinds of records which relate to each other. I assume because of this the relations are defined lazy and object storages are used.

<?php
namespace VendorNameVendorExtensionNameDomainModel;
use TYPO3CMSExtbaseAnnotationORMLazy;
/**
 *
 * @package vendor_extension_name
 *
 */
class Ansprechpartner extends TYPO3CMSExtbaseDomainObjectAbstractEntity {

[...]


/**
 * Organisationseinheit
 *
 * @var TYPO3CMSExtbasePersistenceObjectStorage<VendorNameVendorExtensionNameDomainModelOrganisation>
 * @Lazy
 */
protected $organisationseinheit;

/**
 * Dienstleistungen
 *
 * @var TYPO3CMSExtbasePersistenceObjectStorage<VendorNameVendorExtensionNameDomainModelAnsprechpartnerDienstleistung>
 * @Lazy
 */
protected $dienstleistungen = NULL;

[...]

But here the order of the mixed up classes is reversed.
Nonetheless this might be the reason for the mixing/concatenating of the existing namespaces VendorNameVendorExtensionNameDomainModel[Ansprechpartner] and
TYPO3CMSExtbasePersistenceObjectStorage to the strange class name
VendorNameVendorExtensionNameDomainModelTYPO3CMSExtbasePersistenceObjectStorage, which of course does not exist.


Edit:
insert the usage of
use TYPO3CMSExtbaseAnnotationInject; and
use TYPO3CMSExtbaseAnnotationORMLazy; instead of build in inject and lazy, which has no effect.


Edit 2:

Initialization of storages (example from the class above):

class Ansprechpartner extends TYPO3CMSExtbaseDomainObjectAbstractEntity
{

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

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

Advertisement

Answer

We found out, this is due to the changes within 9.x that relative Namespaces are now supported within Annotations and TypeHints.

Before 9.x, Extbase Reflection always asumed absolute namespaces.

If there is a Method with this signature, that worked before 9.x (which is a Bug) and does not work since 9.x anymore:

public function setSomeStorage(TYPO3CMSExtbasePersistenceObjectStorage $storage) {

This has to be:

public function setSomeStorage(TYPO3CMSExtbasePersistenceObjectStorage $storage) {
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement