Symfony2 doesn't seem to recognize my repository class - symfony

I am encountering the error Undefined method 'findAllCtrs'. The method name must start with either findBy or findOneBy!
I've tried all the other solutions on StackOverflow regarding this problem. I've cleared cache, cleared meta data cache, checked the namespaces and folder entities but still no fix.
Here is my entity:
namespace CFS\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Ref
*
* #ORM\Table(name="ref", indexes={#ORM\Index(name="refno", columns={"refno"}), #ORM\Index(name="ctrno", columns={"ctrno"})})
* #ORM\Entity(repositoryClass="CFS\Bundle\Entity\RefRepository")
*/
class Ref
{
My repository class:
namespace CFS\Bundle\Entity;
use Doctrine\ORM\EntityRepository;
class RefRepository extends EntityRepository
{
public function findAllCtrs()
{
$query = $this->getEntityManager()
->createQuery('
SELECT
r.refno, r.ctrno
FROM
CFSBundle:Ref r
ORDER BY
r.refno DESC
');
try {
return $query->getResult();
} catch(\Doctrine\ORM\NoResultException $e) {
return null;
}
}
}
And I tried calling the method in my controller with:
$em = $this->getDoctrine()->getManager();
$containers = $em->getRepository('CFSBundle:Ref')
->findAllCtrs();
I did noticed that when I generate entities in the command line php app/console doctrine:generate:entities CFSBundle it is not recognizing my RefRepository.php file. What else could I have missed?

I stuck with a similar error too, after spending a day searching for a solution I found a typo in my annotation referencing the repository class.
But I don't see a mistake in the code you provided, hence it should work…
Did you read https://stackoverflow.com/a/15184084/1781752 ?
There seemed to be problems mixing yml mappings and annotations.

Related

Annotation for Symfony validator returns "annotation was never imported exception"

I am trying to use the validator service on a Symfony controller, particularly the uniqueEntity constraint to check if an object with a same id is already on the database. I have successfully used de UUID constraint of the validator on the same project before, using annotations as well. For this reason it seems strange that using the same method wouldn't work.
My annotated entity looks like this:
<?php
//src/Entity/Usuarios.php
namespace App\Entity;
use App\Repository\UsuariosRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass=UsuariosRepository::class)
* #UniqueEntity("idUsuario")
*/
class Usuarios
{
/**
* #ORM\Id() #ORM\Column(name="idUsuario",type="integer", unique=true)
* #Assert\IdUsuario
*/
private $idUsuario;
\** etc.**\
?>
My controller looks like this:
//src/Entity/Usuarios.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpClient\HttpClient;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Empleados;
use App\Entity\Productos;
use App\Entity\ProductoOrden;
use App\Entity\Ordenes;
use App\Entity\Usuarios;
use App\Entity\Ventas;
use App\Entity\Periodos;
require_once('/Users/jaumaf/clases/2020-1/incentivos/src/testData.php');
use const testData\USUARIOS_T;
use const testData\EMPLEADOS_T;
use const testData\PRODUCTOS_T;
use const testData\ORDENES_T;
use const testData\PERIODOS_T;
use const testData\VENTAS_T;
use Psr\Log\LoggerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class LoadDataController extends AbstractController
{
/**
* #Route("/load/data", name="load_data")
*/
public function index(LoggerInterface $logger, ValidatorInterface $validator) {
//los json estan en testData.php
$usuariosArray = json_decode(USUARIOS_T, TRUE);
$empleadosArray = json_decode(EMPLEADOS_T,TRUE);
$productosArray = json_decode(PRODUCTOS_T,TRUE);
$ordenesPorEmpleadoArray = json_decode(ORDENES_T,TRUE);
$periodosArray = json_decode(PERIODOS_T, TRUE);
$ventasPorVendedorArray= json_decode(VENTAS_T, TRUE);
$logger->info('Test constants loaded');
$entities = $this -> mapArraysToObjects($usuariosArray, $empleadosArray, $productosArray, $ordenesPorEmpleadoArray,$ventasPorVendedorArray,$periodosArray);
$logger->info('Entities loaded to memory');
$cont = 0;
$logtable = $this -> logLoadedEntities($cont, $entities);
// Persistencia
$entityManager = $this->getDoctrine()->getManager();
$logger->info('ORM loaded');
// Validator test
$usuario = $entities[0];
$validation = $validator -> validate($usuario);
// this should make the validator throw a uniqueEntity exception, but it throws an annotation exception.
The exception I am getting is:
[Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\IdUsuario" in property App\Entity\Usuarios::$idUsuario was never imported. Did you maybe forget to add a "use" statement for this annotation?
I have tried adding a use statement for Symfony\Component\Validator\Constraints\IdUsuario on my controller as the exception message seems to imply (however, the Symfony guide doesn't mention this step so it should be unneccesary). But it shows exactly the same error.
I also tried making a doctrine migration hoping that the metadata the annotations use somehow updates itself, but It throws the same exception in the command line.
bash-3.2$ php bin/console make:migration
In AnnotationException.php line 54:
[Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\IdUsu
ario" in property App\Entity\Usuarios::$idUsuario was never imported. Did you may
be forget to add a "use" statement for this annotation?
I am new to php and I don't really understand how annotations work. But I've followed the guide in https://symfony.com/doc/current/reference/constraints/UniqueEntity.html. I'm pretty sure I've gone over the syntax thoroughly and as I said it worked before with a different constraint. In addition, the exception is thrown from within the the controller when I make a call to the validate() function. Maybe there is something I'm missing in the controller side or something on the Symfony framework system that I don't know about that might affect the behavior of the validation service?
I would appreciate any guidance. I will be trying to wrap my head over annotations on the meantime.
Thanks
Remove annotation #Assert\IdUsuario from class Usuarios
You copy-pasted it from https://symfony.com/doc/current/reference/constraints/UniqueEntity.html
It's not related to UniqueEntity validation. It's just checking that field is a valid email.

Symfony 4 - Can't access to my entity collection

I've a Symfony 4 project with User entity and SoldeConges Entity.
An user has a SoldeConges collection.
But when I dump the $user->getSoldeConges(), the collection is empty.
My User entity :
/**
* #ORM\OneToMany(targetEntity="App\Entity\SoldeConges", mappedBy="user", orphanRemoval=true)
*/
private $soldeConges;
/**
* #return Collection|SoldeConges[]
*/
public function getSoldeConges(): Collection
{
return $this->soldeConges;
}
And my user has 3 soldeConges :
PhpMyAdmin SoldeConge table :
And when I make a dump in my controller for my User (which is the user number 1) :
$soldeConges = $this->getUser()->getSoldeConges();
dump($soldeConges);
I've :
So, why can not access to my User SoldeConges collection ?
1)To get your soldeConges (this is symfony 3 code, adapt it to 4 ;-) ):
$em = $this->getDoctrine()->getManager();
$soldeCongesRepository= $em->getRepository('AppSoldeConges:SoldeConges');
$soldeConges = $soldeCongeRepository->findBy(['userId'=>$this->getUser()->getId()]);
2)It may be due to Doctrine lazy loading.
Try fetch="EAGER" (it's LAZY by default):
* #ORM\OneToMany(targetEntity="App\Entity\SoldeConges", mappedBy="user", orphanRemoval=true, fetch="EAGER")
Doctrine loads the whole collection in once IF you try to access it. A dump is the memory model at the moment where you place your dump() statement.
If you should render the collection first (or even only if you use the count() method on the collection) and then use the dump() statement you will see that your collection has been loaded. This is the system called lazy loading. It will execute a second query when needed. But as you may know if two queries could get one query then it should be better and faster.
On the other hand if you have entities with large collections this could get a serious problem. In that case you could use "extra lazy loading". (See the docs)
Anyway if you want to get your collections loaded immediately with your entities then you could use your own DQL query that have one or more JOINS. Below an example of your Repository with a new function called findAllWithJoin. Call that function from your controller instead of findAll().
namespace App\Repository;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
class UserRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, User::class);
}
public function findAllWithJoin()
{
$entityManager = $this->getEntityManager();
$query = $entityManager->createQuery('SELECT u, sc FROM User u JOIN u.soldeConges sc');
return $query->execute();
}
}

Object not found but working when created by "new"

It's working:
use AppBundle\Entity\Product;
use AppBundle\Entity\ProductPriceAccept;
public function editAction(Product $product)
{
$ppa = new ProductPriceAccept();
// further some operations on $product
}
But it doesn't want to work:
use AppBundle\Entity\Product;
use AppBundle\Entity\ProductPriceAccept;
public function editAction(Product $product, ProductPriceAccept $ppa)
{
$ppa->setPrice();
// further some operations on $product
}
I get:
AppBundle\Entity\ProductPriceAccept object not found.
Entity\ProductPriceAccept.php is:
// src/AppBundle/Entity/ProductPriceAccept.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="Product_Price_Accept")
*/
class ProductPriceAccept
{
// ...
}
I'm a little confused because usually type hint works well for me and as you can see up it works in similar situation for Product Entity. First solution works fine but I want to find out how the second makes problem. I cleared cache, checked typos. No idea what can do more.
With a single parameter to be read, it can automatically read the repository.
With more than one, it needs some help.
The id option specifies which placeholder from the route gets passed to the repository method used. If no repository method is specified, find() is used by default.
This also allows you to have multiple converters in one action:
So, you will need an explicit #ParamConverter for ProductPriceAccept - you will also likely need use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; line.
/**
* #Route("/blog/{id}/comments/{comment_id}")
* #ParamConverter("comment", class="SensioBlogBundle:Comment",
* options={"id" = "comment_id"})
*/
public function showAction(Post $post, Comment $comment)
{
}
from: #ParamConverter.

Knplabs translatable: How to find an entry by a translatable field?

I have an entity with the Knp Doctrine behaviors Translatable and Sluggable. Everything works fine so when I create or update an entry there is a slug for each language generated from the title.
The question ist how can i find an entry by a translated slug?
This will throw an error "has no field 'slug'":
$this->getDoctrine()->getRepository('AcmeTestBundle:News')->findOneBySlug($slug);
Unless someone has a smarter way of doing this then you will need to create a custom repository method that performs a join to the entity translations table to perform your lookup:
use Doctrine\ORM\EntityRepository;
/**
* NewsRepository
*/
class NewsRepository extends EntityRepository
{
public function findOneBySlug($slug)
{
$qb = $this->createQueryBuilder('n')
->select('n, t')
->join('n.translations', 't')
->where('t.slug = :slug')
->setParameter('slug', $slug);
return $qb->getQuery()->getSingleResult();
}
}
I have found that this method works, although I am still curious if there is a more generic solution to this
Try This:
$this->getDoctrine()
->getRepository('AcmeTestBundle:News')
->findOneBy(array("slug"=>$slug));
Hope this helps.

Using distinct Doctrine2

I am developing an application in symfony2 and using doctrine2. I created a custom repository class that has one function:
<?php
namespace Anotatzailea\AnotatzaileaBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* InterpretatzeaRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class InterpretatzeaRepository extends EntityRepository
{
public function getInterpDesberdinak($value)
{
$qb = $this->createQueryBuilder('c')
->select('DISTINCT c.attribute')
->where('c.fer = :Value')
->setParameter('Value', $value);
$Emaitza = $qb->getQuery()->getResult();
return $Emaitza;
}
}
What I want to get with this function is an array of all the "Interpretatzea" objects that have a distinct c.attribute and all have c.fer = value. Is the query correct? I would also want to know how to pass the value parameter to the repository function. Thanks
A cursory look at your repository method suggests it looks okay :) IIRC, I think the use of DISTINCT there is fine. If you do have problems you can always do a GROUP BY instead.
As for calling the repo method in a controller and passing a $value variable to it, that's pretty straightforward; for example:
// in your controller
$value = 'foo';
// get doctrine connection from DI, etc.
$em = $this->getDoctrine()
->getEntityManager();
// get the repository object for your
// entity and call your repository method
$result = $em->getRepository('AnotatzaileaAnotatzaileaBundle:Interpretatzea')
->getInterpDesberdinak($value);
// ... do something with your $result here
Note you use a concatenated version of your namespace and bundle, followed by a colon and the entity; e.g: AcmeTestBundle:User
Hope this helps :)

Resources