0

I am trying to bring my symfony application up to 4.x and the (hopefully) last deprecation notice I get in version 3.4.1 is this:

Relying on service auto-registration for type "AppBundle\Entity\ExtraOpening\price" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "AppBundle\Entity\ExtraOpening\price" instead.

Relying on service auto-registration for type "AppBundle\Entity\ExtraOpening\DebitPeriod" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "AppBundle\Entity\ExtraOpening\DebitPeriod" instead.

I have 7 more of those same notices, one for each one of my application's entities it seems. I don't think the error messages are quite accurate, I don't think I need to define a service for every entity it is to be used with (?) I suppose I'm just connecting the entity manager to the service in an inaccurate way or something?

This is my services.yml

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'

    # shouldn't it be like this then:
    # AppBundle\Service\globalHelper:
    #     arguments: ['@service_container', '@doctrine.orm.entity_manager']

    globalHelper:
        class: AppBundle\Service\globalHelper
        public: true
        arguments: ['@service_container', '@doctrine.orm.entity_manager']

This is (the relevant part of) my service class

    <?php
    namespace AppBundle\Service;
    
    use Symfony\Component\DependencyInjection\ContainerInterface as Container;
    //use Doctrine\ORM\EntityManager as EntityManager; //gave deprecation notice, profiler suggested to change to below and the deprecation notice disappeared.
    use Doctrine\ORM\EntityManagerInterface as EntityManager;
    
    
    class globalHelper {
    
        private $container;
        private $em;
    
        public function __construct(Container $container, EntityManager $em) {
            $this->container = $container;
            $this->em = $em;
        }

        /* For putting a message in the flashbag */
        public function flash($type,$message) {
            $this->container->get('session')->getFlashBag()->add($type, $message);
        }

A sample of how the service is used in a controller:

    /**
     * Creates a new price entity.
     *
     */
    public function newAction(Request $request, globalHelper $helper)
    {
        //$helper = $this->get('globalHelper'); //old way of instantiating the helper class. Still works but it seems this is going out of style
        $price = new Price();
        //$form = $this->createForm('AppBundle\Form\priceType', $price);
        $form = $this->createForm(\AppBundle\Form\priceType::class, $price);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
           
           //TODO: check for conflict with existing price entity

            $em = $this->getDoctrine()->getManager();
            $em->persist($price);
            $em->flush($price);

            $helper->flash('success','Lade till ett prisavtal.');
            return $this->redirectToRoute('price_index');

        }

        return $this->render('price/new.html.twig', array(
            'price' => $price,
            'form' => $form->createView(),
        ));
    }

The price entity is probably irrelevant to the case, but I paste it here just in case

<?php

namespace AppBundle\Entity\ExtraOpening;

use Doctrine\ORM\Mapping as ORM;

/**
 * price
 *
 * @ORM\Table(name="price")
 * @ORM\Entity
 */
class price
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateFrom", type="date")
     */
    private $dateFrom;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateTo", type="date")
     */
    private $dateTo;

    /**
     * @var int
     *
     * @ORM\Column(name="hourPrice", type="integer")
     */
    private $hourPrice;


    /**
    * @var object \AppBundle\Entity\ACRGroup
    *  
    * @ORM\ManyToOne(targetEntity="\AppBundle\Entity\ACRGroup")
    * @ORM\JoinColumn(name="acr_group", referencedColumnName="id", nullable=false)
    */
    protected $acr_group;

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set dateFrom
     *
     * @param \DateTime $dateFrom
     *
     * @return price
     */
    public function setDateFrom($dateFrom)
    {
        $this->dateFrom = $dateFrom;

        return $this;
    }

    /**
     * Get dateFrom
     *
     * @return \DateTime
     */
    public function getDateFrom()
    {
        return $this->dateFrom;
    }

    /**
     * Set dateTo
     *
     * @param \DateTime $dateTo
     *
     * @return price
     */
    public function setDateTo($dateTo)
    {
        $this->dateTo = $dateTo;

        return $this;
    }

    /**
     * Get dateTo
     *
     * @return \DateTime
     */
    public function getDateTo()
    {
        return $this->dateTo;
    }

    /**
     * Set hourPrice
     *
     * @param integer $hourPrice
     *
     * @return price
     */
    public function setHourPrice($hourPrice)
    {
        $this->hourPrice = $hourPrice;

        return $this;
    }

    /**
     * Get hourPrice
     *
     * @return int
     */
    public function getHourPrice()
    {
        return $this->hourPrice;
    }



    /**
     * Set acrGroup
     *
     * @param \AppBundle\Entity\ACRGroup $acrGroup
     *
     * @return Analysis
     */
    public function setAcrGroup(\AppBundle\Entity\ACRGroup $acrGroup)
    {
        $this->acr_group = $acrGroup;

        return $this;
    }

    /**
     * Get acrGroup
     *
     * @return \AppBundle\Entity\ACRGroup
     */
    public function getAcrGroup()
    {
        return $this->acr_group;
    }
    
}
Matt Welander
  • 8,234
  • 24
  • 88
  • 138
  • Try the accepted solution [here](https://stackoverflow.com/questions/47907721/relying-on-service-auto-registration-error-on-orm-entity). What is happening is that somewhere in your code you are injecting these entities and autowire wants to make a service of them. Those problem classes should be excluded from autowire. And on a different topic your globalService is probably not going to be much help. By default services are private which means $container->get will not work so accessing the container is somewhat futile. – Cerad Jul 26 '22 at 19:34
  • The $container->get way of accessing it is commented out in my sample above, that was how I used to do it. Now though I pass it in as an argument of the function (see sample above). Though both ways still work in 3.4 (the service has public:true as you can see above), should it best be done differently? – Matt Welander Jul 26 '22 at 20:13
  • Like the person in that other question you linked (thank you btw) I tried using exclude: '../../src/AppBundle/Entity' in my services.yml (to try and tell Symfony to not attempt auto-wire on possible entities I may use with the service) but it made no difference. Adding container.autowiring.strict_mode: true in the parameters section of config.yml did however remove the deprecation notices. But then I'm a bit unsure what other possibly unwanted behaviors I have introduced with that =D – Matt Welander Jul 26 '22 at 20:25
  • The error was actually a false positive and will basically go away once you move to S4 (or perhaps S6 is you decide to save yourself some unnecessary work). The error was never about defining the entities as services. The error was about classes which have entities as constructor arguments. Autowire was trying to make entity services for them. In any event you should be good. – Cerad Jul 26 '22 at 20:58
  • As far as injecting the container into anything including your globalService is that you won't be able to use it for anything since services are private. In fact somewhere in S4 the container_service is no longer even defined. As an amusing side note: `app/console debug:container globalHelper` will reveal two services. One will have an id of 'globalHelper' and the other 'AppBundle\Service\globalHelper`. I'll leave it up to your to ponder why and perhaps understand which service is used in which circumstances. – Cerad Jul 26 '22 at 21:03

0 Answers0