Can't call custom repository function in Symfony2 - php

We're having problems calling a certain custom entity repository function from our controller in a Symfony2 project. We have successfully done it before with other entities so we're probably missing something and I can't figure out what it could be.
Our repository class looks like this:
<?php
namespace OurSite\Bundle\OurBundle\Entity;
use Doctrine\ORM\EntityRepository;
class BlogRepository extends EntityRepository
{
public function findPreviousPosts($limit = 6)
{
$q = $this->createQueryBuilder('q')
->where('q.category = :category')
->setMaxResults($limit)
->add('orderBy', 'q.published ASC')
->getQuery();
$res = $q->getResult();
return $res;
}
}
The entity:
<?php
namespace OurSite\Bundle\OurBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
/**
* OurSite\Bundle\OurBundle\Entity\Blog
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="OurSite\Bundle\OurBundle\Entity\BlogRepository")
*/
class Blog {
// Non-relevant stuff here
}
When we call the method like this:
$em = $this->getDoctrine()->getEntityManager();
$previousPosts = $em->getRepository('OurSiteOurBundle:Blog')->findPreviousPosts();
We get this:
Undefined method 'findPreviousPosts'. The method name must start with either findBy or findOneBy!
If we do echo get_class($em->getRepository('OurSiteOurBundle:Blog')); it outputs BlogRepository, as expected.
What could be causing the problem? We have a superfluous bundle directory in the project but I'm guessing that can't be causing it?

From the source you provided, this may not be your issue, but it may save others some search time.
I was coming across the same "must start with either findBy or..." error, and it turns out in my Entity definition I had accidentally made a call to the #ORM\Entity annotation Twice. The first time I used it properly and set the repositoryClass, but the second time I just used it by itself (as with an Entity that wouldn't have a custom repository) and so that overwrote the previous repositoryClass definition.
/**
*
* #ORM\Entity(repositoryClass="Company\TestBundle\Entity\MyEntityRepository")
* #ORM\Table(name="testing_my_entity")
* #ORM\Entity
*/
class MyEntity
{
etc...
}

If you get this error: The method name must start with either findBy or findOneBy! that means that your custom repository isn't loaded.
Check for typos in the code, clear cache, make sure "OurSiteOurBundle" is the actual shortcut name.

I had the same problem. I've seen many posts about that but nothing solved it.
Finally I found out that was because I was previously using generated yml files, so Doctrine didn't read annotations for mapping !
So just be sure you don't have any yml/xml Doctrine files.
And then :
app/console doctrine:cache:clear-metadata

Did you used this entity before? I see strange entity shortcut for Blog
OurSiteOurBundle:Blog
but your Blog have OurSite\ Bundle\OurBundle\Entity namespace. I think it should be
OurSiteBundleOurBundle:Blog
and entity manager points you to wrong repository class

If use xml for mapping(pass tested):
Update xml or yml mapping file, add repository-class attribute:
<entity name="Ccd\Bundle\FrontendBundle\Entity\UvUpdatePageContent" table="uv_update_page_content" **repository-class="Ccd\Bundle\FrontendBundle\Entity\UvUpdatePageContentRepository"**>
http://doctrine-mongodb-odm.readthedocs.org/en/latest/cookbook/mapping-classes-to-orm-and-odm.html
Then update doctrine cache:
php app/console doctrine:cache:clear-metadata
use yml(not tested):
Acme\DemoBundle\Entity\Post:
type: entity
table: posts
RepositoryClass: Acme\DemoBundle\Entity\PostRepository

Related

Symfony routing annotation Entity

I need to get 2 entity objects from the path parameter in Symfony 3.
From the document, I can do:
/**
* #Route("/blog/{id}/comments/{comment_id}")
* #Entity("comment", expr="repository.find(comment_id)")
*/
public function showAction(Post $post, Comment $comment)
{
}
However, I could not find out where that #Entity comes from. The page return with error:
[Semantical Error] The annotation "#Entity" in method ABCBundle\Controller\ABCController::editAction() was never imported. Did you maybe forget to add a "use" statement for this annotation? in /srv/www/symfony3/src/ABCBundleController (which is being imported from "/srv/www/symfony3/src/ABCBundle/Resources/config/routing.yml").
Does anyone know?
You may want to add this use statement:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
See SensioFrameWorkExtraBundle at github

Undefined method 'findFoodsByName'. The method name must start with either findBy or findOneBy

I have already read the existing pages here regarding the same error message declared in the title. Like for example this here:
The method name must start with either findBy or findOneBy. Undefined method Symfony?
However, i did not find working solution. I have done everything according to the manual:
http://symfony.com/doc/3.0/book/doctrine.html#custom-repository-classes
I'm using annotation based configuration and here is the start of the food class:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Food
*
* #ORM\Table(name="food")
* #ORM\Entity(repositoryClass="AppBundle\Entity\FoodRepository")
*/
However, the command:
php bin/console doctrine:generate:entities AppBundle
does not generate the FoodRepository repo, so i had to do it manually. Here is the code of the FoodRepository:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\EntityRepository;
class FoodRepository extends EntityRepository
{
public function findFoodsByName()
{
return $this->getEntityManager()
->createQuery(
'SELECT f FROM AppBundle:Food f WHERE f.foodname LIKE :food'
)
->getResult();
}
}
and here is the slice from the controller:
$em = $this->getDoctrine()->getManager();
$foods = $em->getRepository('AppBundle:Food')
->findFoodsByName();
I have also tried to empty the Doctrine cache with command:
php app/console doctrine:cache:clear-metadata
without results. The problem persists.
Has anyone had the same problem with Symfony and what did you do to solve the problem?

Doctrine2 Entity Manager cannot find Custom Repository Class in namespace

I have Silex setup with Doctrine2 ORM. I am trying to build a pagination class that I can use with my entities. I am well aware of the existing pagination classes that exist within Doctrine2 but because this project is for my school research I am trying to create this component myself.
Below is the fatal error I get when accessing this page:
Fatal error: Class 'PlayGround\Model\Helper\UserRepository' not found in D:\web\playground-solutions\vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php on line 689
I have defined an interface called PaginateableInterface with two methods count and paginate. I went on to define a custom EntityRepository class that extends Doctrine\ORM\EntityRepository. Below is my custom EntityRepository.
<?php
namespace PlayGround\Service\Doctrine;
use Doctrine\ORM\EntityRepository as ParentEntityRepository;
class EntityRepository extends ParentEntityRepository{
public function count(){
$em = $this->getEntityManager();
$builder = $em->createQueryBuilder();
/**
* ToDo: #entity
*
* Still need to find a better way of getting entity class name.
*/
$entity = $em->getClassMetadata(get_class(__CLASS__))->getName();
//Dynamically get a count of records on any entity we happen to call this on.
$builder->select($builder->expr()->count('e'))
->from($entity, 'e');
$query = $builder->getQuery();
//Try-Catch block ommitted
return $query->getSingleScalarResult();
}
}
<?php
namespace PlayGround\Model\Helper;
use PlayGround\Service\Doctrine\EntityRepository as CustomRepository;
use PlayGround\Contract\PaginateableInterface as IPaginate;
class UserRepository extends CustomRepository implements IPaginate
{
}
In my understanding this should suffice as the count and paginate methods are sitting within the custom repository.
Inside my Paginator class I call the entity I want to paginate as shown below:
<?php
//Paginator class
$model = $this->getModel($model);
//Count should be inherited from CustomRepository aliased object.
$totalRecords = $model->count();
Below is another pierce of meet with regards to this where I add an annotation to my model to point it to the repository class it is suppose to use.
<?php
namespace Application\Model\Entity;
use Doctrine\ORM\Mapping as ORM;
use Application\Model\Entity\UserGroup;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
* #ORM\Entity(repositoryClass="PlayGround\Model\Helper\UserRepository")
*/
class User{ /* Rest of the code goes here... */ }
Given all this setup what could I have missed in getting this to work? I have even ran two commands on my doctrine console but that didn't help either.
Luyanda.Siko#ZACT-PC301 MINGW64 /d/web/playground-solutions
$ php app/Console/bin/doctrine.php orm:clear-cache:metadata
Clearing ALL Metadata cache entries
Successfully deleted cache entries.
Luyanda.Siko#ZACT-PC301 MINGW64 /d/web/playground-solutions
$ php app/Console/bin/doctrine.php orm:clear-cache:query
Clearing ALL Query cache entries
Successfully deleted cache entries.
EDIT:
Below is my file structure found in D:\web\playground-solutions.
You declare twice #ORM\Entity. Once with the repositoryClass and once without. Remove the one without:
#ORM\Entity
and leave this:
#ORM\Entity(repositoryClass="PlayGround\Model\Helper\UserRepository")
#ORM\HasLifecycleCallbacks should be declared without parentheses ()...
Also make sure that the EntityRepository is in the correct namespace and the corresponding folder:
your namespace is PlayGround\Model\Helper\UserRepository meaning the file should be in folder PlayGround\Model\Helper and the class file name should be UserRepository.php.
Fix and check that and if it still doesn't work leave a comment.
UPDATE:
Your UserRepository is in the wrong module. Is now in app should be in PlayGround
The file should be in:
src/PlayGround/Model/Helper/UserRepository.php
It's all about that problem.
Clearly this has really consumed my thought process. All I was doing was pointing to an incorrect namespace as pointed out by #Witt.
I changed my annotation entry in the User entity and the error went away.
<?php
/** #ORM\Entity(repositoryClass="Application\Model\Helper\UserRepository") */
Thanks you guys.

Doctrine does not create a new table from an - already exist - entity class?

I have an entity defined as:
<?php
namespace Acme\myBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Acme\CoreBundle\Model\Message;
/**
* Facebook Post
* #ORM\MappedSuperclass
* ORM\Table(name="acme_facebookPost")
* ORM\Entity(repositoryClass="Acme\FacebookBundle\Entity\FacebookPostRepository")
*/
class FacebookPost extends Message
{
// entity properties
}
This entity class was created somewhere else in my project and I just moved it here.
When I run following commands to generate the entity and update my tables, it runs without error but, I can not see acme_facebookPost table in my database.
php app/console doctrine:generate:entities AcmeFacebookBundle:FacebookPost
Generating entity "Acme\FacebookBundle\Entity\FacebookPost"
> backing up FacebookPost.php to FacebookPost.php~
> generating Acme\FacebookBundle\Entity\FacebookPost
and then:
$ php app/console doctrine:schema:update --force
Nothing to update - your database is already in sync with the current entity metadata.
Can anyone tell me what I'm doing wrong here?
Thanks.
P.S.
I need to add that I'm using annotation and there is no metadata anywhere inside my bundle.
It seems that you forgot to add # before ORM\Entity(... and ORM\Table(.. hence your class is not identified as an entity

Symfony/Doctrine: Class is not a valid entity or mapped super class

I'm getting the "Class PriceOrQuality\POQBundle\Entity\Tag is not a valid entity or mapped super class error. I've have checked all the answers to similar questions, but I cannot seem to grasp the problem.
The error is thrown by my Repository Class
<?php
namespace PriceOrQuality\POQBundle\Entity\Repository;
use Doctrine\ORM\EntityRepository as ER;
use PriceOrQuality\POQBundle\Entity\Tag;
use Doctrine\ORM\EntityManager;
/**
* EntityTagsRepository
*
*/
class EntityTagsRepository extends ER
{
public function getTagsForTagCloud($entity_ids = null, $tag_id = null) {
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb->select(array('IDENTITY(et.tag) as id, COUNT(et.tag) as tag_id_count, LOWER(t.tag) as tag'));
$qb->from('PriceOrQuality\POQBundle\Entity\EntityTag', 'et');
$qb->leftjoin('PriceOrQuality\POQBundle\Entity\Tag','t', 'WITH', 'et.tag = t.id');
$qb->groupBy('et.tag');
$qb->addOrderBy('tag_id_count','DESC');
$qb->setMaxResults(20);
return $qb->getQuery()
->getResult();
}
}
The Tag class is defined in this file (Tag.php) (definition only):
<?php
namespace PriceOrQuality\POQBundle\Entity;
// src/PriceOrQuality/POQBundle/Entity/Tag.php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use PriceOrQuality\POQBundle\Entity\EntityTag;
use PriceOrQuality\POQBundle\Entity\User;
use JMS\SerializerBundle\Serializer\Serializer;
/**
* #ORM\Entity(repositoryClass="PriceOrQuality\POQBundle\Entity\Repository\TagsRepository")
* #ORM\Table(name="tags")
* #ORM\HasLifecycleCallbacks
*/
Does any of you smart guys have any idea on where to start with the debugging?
Thanks in advance,
Rune
Found the issue.
I had a //#todo after the meta definition and before the class definition. Apparently that screwed up the mapping, as it was not mapped in doctrine.
Moving the //#todo and rerunning the mapping fixed the problem.
For whomever finds this question with similar problems try running:
php app/console doctrine:mapping:info
It will show you if you have problems in the mapping structure in doctrine
Thanks for your time guys.
Cheers,
Rune
Read up a bit on query builder. It's easier and different than a sql query. No need for join conditions.
This (for starters):
$qb->leftjoin('PriceOrQuality\POQBundle\Entity\Tag','t', 'WITH', 'et.tag = t.id');
Should just be:
$qb->leftJoin('et.tag','t');
There might be more problems but that will get you started.
http://docs.doctrine-project.org/en/latest/reference/query-builder.html

Categories