stivlo
stivlo

Reputation: 85536

Symfony/Doctrine

I am currently learning Symfony and Doctrine by reading the docs.

I don't understand the difference between find and findOneById. I tried to use them both in this simple example and it looks they do the same thing to me.

$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findOneById($id);

Are they really the same thing or there is some difference? And where I can find the detailed documentation for all these methods?

Upvotes: 2

Views: 1733

Answers (6)

pavan ganvani
pavan ganvani

Reputation: 102

// query by the primary key (usually "id")
$product = $repository->find($id);

// dynamic method names to find based on a column value
$product = $repository->findOneById($id);
// $foo is any name which you want to find from database
$product = $repository->findOneByName($foo);

Upvotes: 2

isaiasmac
isaiasmac

Reputation: 316

Is the same thing, but I prefer the findOneBy method. It's more clear.

Upvotes: 0

schemar
schemar

Reputation: 632

It calls the same method in the end.

findByKey('value')

Is basically the same as

findBy(array('key' => 'value'))

Where key is the property of the entity and value is the value of the property.

findById($id)

Is a special case of the above. And so is

find($id)

All of these methods execute the same query in the end. However, there is a difference in

findBy()

and

findOneBy()

Where findOneBy() only returns a single result and findBy will return all the results satisfying the demands.

However, in general it is considered good practice to use DQL queries instead. Consider lazy loading, array hydration, prepared statements, etc. This is an interesting article on the topic: Some Doctrine 2 Best Practices

Upvotes: 1

mmoreram
mmoreram

Reputation: 684

In fact, is not the same thing.

Think about it. If you call "findBy()" you assume you'll receive a collection of entities ( 0, 1 or more than one ). So, to get all results, you'll need to iterate ArrayCollection or just get first ( $result->first() ).

If your query is by a unique key ( As this case ), you can just get unique entity by calling "getOneById()" and you will receive the entity as result.

/**
 * Retrieving Product with 'findOneBy'
 */
$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findOneById($id);

/**
 * Retrieving Product with 'findBy'
 */
$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findById($id)
                ->first();

Semantically, the first one it the best.

*TIP

Entity should be called just Product. Why? Because is under "/Entity" folder ( Almost, should... ), and namespace will contain info about "What is exactly Product"

Upvotes: 2

greg0ire
greg0ire

Reputation: 23265

There is an API here I don't think there is any difference: the two methods, when call the way you call them, do this:

return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);

But find will be quicker and far quicker in some cases, because it doesn't use the __call magic method, and because find() checks a map of the current unit of work before whereas load() doesn't (see the @todo):

/**                                                                         
 * Loads an entity by a list of field criteria.                             
 * ...
 * 
 * @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
 */                                                                         
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0) 

So prefer find(), findOneById() is just a less efficient method to do the same thing.

Upvotes: 2

rid
rid

Reputation: 63580

In your case, they happen to do the same thing. Looking at this example, you'll notice that find() looks for the field named after the primary key. findOneBy<Field>() will explicitly use the field in the name of the method, even if it's not the primary key, and will return the first record. So, in the end, if the primary key is indeed named id, then both will do the same thing.

// query by the primary key (usually "id")
$product = $repository->find($id);

// dynamic method names to find based on a column value
$product = $repository->findOneById($id);
$product = $repository->findOneByName('foo');

Upvotes: 12

Related Questions