SonataDoctrineORMAdminBundle: Does not work: Admin for entity with a composite key in 3.6.0

Environment

Sonata packages

$ composer show --latest 'sonata-project/*'
sonata-project/admin-bundle              3.35.2 3.35.2 The missing Symfony Admin Generator
sonata-project/block-bundle              3.12.1 3.12.1 Symfony SonataBlockBundle
sonata-project/cache                     2.0.1  2.0.1  Cache library
sonata-project/classification-bundle     3.6.1  3.6.1  Symfony SonataClassificationBundle
sonata-project/core-bundle               3.9.1  3.9.1  Symfony SonataCoreBundle
sonata-project/datagrid-bundle           2.3.1  2.3.1  Symfony SonataDatagridBundle
sonata-project/doctrine-extensions       1.0.2  1.0.2  Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle 3.6.0  3.6.0  Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       2.5.0  2.5.0  Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.9.0  1.9.0  Lightweight Exporter library
sonata-project/formatter-bundle          3.4.1  3.4.1  Symfony SonataFormatterBundle
sonata-project/google-authenticator      2.1.0  2.1.0  Library to integrate Google Authenticator into a PHP project
sonata-project/intl-bundle               2.4.1  2.4.1  Symfony SonataIntlBundle
sonata-project/media-bundle              3.13.0 3.13.0 Symfony SonataMediaBundle
sonata-project/user-bundle               3.6.0  4.2.1  Symfony SonataUserBundle

Symfony packages

$ composer show --latest 'symfony/*'
symfony/assetic-bundle     v2.8.2  v2.8.2  Integrates Assetic into Symfony2
symfony/monolog-bundle     v2.12.1 v3.2.0  Symfony MonologBundle
symfony/phpunit-bridge     v2.8.40 v4.0.10 Symfony PHPUnit Bridge
symfony/polyfill-apcu      v1.8.0  v1.8.0  Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-ctype     v1.8.0  v1.8.0  Symfony polyfill for ctype functions
symfony/polyfill-intl-icu  v1.8.0  v1.8.0  Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring  v1.8.0  v1.8.0  Symfony polyfill for the Mbstring extension
symfony/polyfill-php54     v1.8.0  v1.8.0  Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
symfony/polyfill-php55     v1.8.0  v1.8.0  Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
symfony/polyfill-php56     v1.8.0  v1.8.0  Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70     v1.8.0  v1.8.0  Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util      v1.8.0  v1.8.0  Symfony utilities for portability of PHP codes
symfony/security-acl       v3.0.1  v3.0.1  Symfony Security Component - ACL (Access Control List)
symfony/swiftmailer-bundle v2.6.7  v3.2.2  Symfony SwiftmailerBundle
symfony/symfony            v2.8.40 v4.0.10 The Symfony PHP framework

PHP version

$ php -v
PHP 7.1.13-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jan  5 2018 13:26:45) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.13-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans

Subject

I have entity with composite id:

AppBundle\Entity\DomainOffice:
    type: entity
    table: app__domain_office
    id:
        Domain:                                     { associationKey: true }
        Office:                                     { associationKey: true }
    fields:
        position:                                   { type: bigint, nullable: false, options: { unsigned: false } }
    manyToOne:
        Domain:
            targetEntity:                           AppBundle\Entity\Domain
            inversedBy:                             DomainOffices
            joinColumn:                             { name: region_id, referencedColumnName: departure_city_id }
        Office:
            targetEntity:                           AppBundle\Entity\Office
            joinColumn:                             { name: office_id, referencedColumnName: id }
    lifecycleCallbacks: {  }

Config for admin: services.yml

services:
    app.admin.domain_office:
        class: AppBundle\Admin\DomainOfficeAdmin
        arguments: [~, AppBundle\Entity\DomainOffice, AppBundle:DomainSortAdmin]
        tags:
            - { name: sonata.admin, manager_type: orm, group: "Sorting", label: "Domain offices" }
        public: true

Admin class

<?php

namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Route\RouteCollection;

class DomainOfficeAdmin extends AbstractAdmin
{
    protected function configureRoutes(RouteCollection $collection)
    {
        $collection->remove('create');
        $collection->remove('delete');
        $collection->add('up', $this->getRouterIdParameter() . '/up');
        $collection->add('down', $this->getRouterIdParameter() . '/down');
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->add('Domain', null, ['label' => 'Domain'])
            ->add('Office', null, ['label' => 'Office'])
            ->add('position', null, ['label' => 'Position'])
            ->add('_action', null, array(
                'actions' => array(
                    'up' => array('template' => 'AppBundle:Admin:Sort/list__action_up.html.twig',),
                    'down' => array('template' => 'AppBundle:Admin:Sort/list__action_down.html.twig',),
                ),
            ));
    }
}

Steps to reproduce

After update SonataDoctrineORMAdminBundle from 3.5.x to 3.6.0 admin (/admin/app/domainregion/list) dont work. Has an error:

Single id is not allowed on composite primary key in entity AppBundle\Entity\DomainOffice

Expected results

I must have the list of entities. It work in 3.5.x version, but i have error in 3.6.0 version SonataDoctrineORMAdminBundle

Actual results

Stack Trace
in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php at line 424   -
     */
    public static function singleIdNotAllowedOnCompositePrimaryKey($entity)
    {
        return new self('Single id is not allowed on composite primary key in entity '.$entity);
    }
    /**
at MappingException ::singleIdNotAllowedOnCompositePrimaryKey ('AppBundle\Entity\DomainOffice') 
in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php at line 1780   + 
at ClassMetadataInfo ->getSingleIdentifierFieldName () 
in vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php at line 64   + 
at CountWalker ->walkSelectStatement (object(SelectStatement)) 
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/TreeWalkerChain.php at line 113   + 
at TreeWalkerChain ->walkSelectStatement (object(SelectStatement)) 
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 380   + 
at Parser ->parse () 
in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php at line 281   + 
at Query ->_parse () 
in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php at line 293   + 
at Query ->_doExecute () 
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 962   + 
at AbstractQuery ->executeIgnoreQueryCache (null, '4') 
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 917   + 
at AbstractQuery ->execute (null, '4') 
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 797   + 
at AbstractQuery ->getSingleResult ('4') 
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 826   + 
at AbstractQuery ->getSingleScalarResult () 
in vendor/sonata-project/doctrine-orm-admin-bundle/src/Datagrid/Pager.php at line 48   + 
at Pager ->computeNbResult () 
in vendor/sonata-project/doctrine-orm-admin-bundle/src/Datagrid/Pager.php at line 65   + 
at Pager ->init () 
in vendor/sonata-project/admin-bundle/src/Datagrid/Datagrid.php at line 179   + 
at Datagrid ->buildPager () 
in vendor/sonata-project/admin-bundle/src/Datagrid/Datagrid.php at line 262   + 
at Datagrid ->getForm () 
in vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php at line 167   + 
at CRUDController ->listAction () 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 135   + 
at HttpKernel ->handleRaw (object(Request), '1') 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 57   + 
at HttpKernel ->handle (object(Request), '1', true) 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php at line 67   + 
at ContainerAwareHttpKernel ->handle (object(Request), '1', true) 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 183   + 
at Kernel ->handle (object(Request)) 
in web/app_dev.php at line 30   + 

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 22 (17 by maintainers)

Commits related to this issue

Most upvoted comments

still not working

@Soullivaneuh Hm, I will investigate and fix issue.

I upgraded to get this fix and now I’m getting a new error which I think is related to the fix: [Semantical Error] line 0, col 31 near 'brand,'-',o.user))': Error: Invalid PathExpression. Must be a StateFieldPathExpression.

Stack trace: in vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php (line 65) in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php::semanticalError (line 491) in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php->semanticalError (line 806) in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php->processDeferredPathExpressions (line 271) in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php->getAST (line 359) in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php->parse (line 283) in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php->_parse (line 295) in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php->_doExecute (line 957) in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php->executeIgnoreQueryCache (line 912) in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php->execute (line 793) in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php->getSingleResult (line 821) in vendor/sonata-project/doctrine-orm-admin-bundle/src/Datagrid/Pager.php->getSingleScalarResult (line 45) in vendor/sonata-project/doctrine-orm-admin-bundle/src/Datagrid/Pager.php->computeNbResult (line 62) in vendor/sonata-project/admin-bundle/src/Datagrid/Datagrid.php->init (line 179) in vendor/sonata-project/admin-bundle/src/Datagrid/Datagrid.php->buildPager (line 262) in vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php->getForm (line 168) in vendor/symfony/http-kernel/HttpKernel.php->listAction (line 149) in vendor/symfony/http-kernel/HttpKernel.php->handleRaw (line 66) in vendor/symfony/http-kernel/Kernel.php->handle (line 188)

This is my entity:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

class BrandRole
{

    const ROLE_LEVEL_CONSULTANT = 0;
    const ROLE_LEVEL_BRAND_ADMIN = 1;
    const READABLE_ROLE_LEVELS = [
        self::ROLE_LEVEL_CONSULTANT => 'Consultant',
        self::ROLE_LEVEL_BRAND_ADMIN => 'Brand Administrator',
    ];

    /**
     * @var Brand|null $brand The Brand that the brand role is for
     *
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Brand", inversedBy="jobs")
     * @ORM\JoinColumn(name="brand_id", referencedColumnName="id", onDelete="CASCADE")
     * @Assert\NotNull
     */
    private $brand = null;

    /**
     * @var User|null $user The User that is granted the brand role

     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
     * @Assert\NotNull
     */
    private $user = null;

    /**
     * @var int $level An enumerated type with possible values: 0: consultant, 1: brand administrator
     *
     * @ORM\Column(type="integer")
     * @Assert\NotBlank
     */
    private $level = 0;
    
    // Methods excluded for brevity
}