Symfony2 and Doctrine $ em-> persist VS $ em-> merge
Hi I have a quick question regarding Doctrine and the difference between merge()
andpersist()
I have a class NewsBuilder
:
- This takes a news object and checks if it exists in the database if it sets the object values to the data and returns an object.
- If it doesn't exist, it creates a new News Entity that sets the data and returns an object
namespace FantasyPro\DataBundle\Builder;
use FantasyPro\DataBundle\Entity\News;
use FantasyPro\DataBundle\Helpers\DateHelper;
class NewsBuilder
{
/**
* @var DateHelper $dateHelper
*/
private $dateHelper;
public function __construct( DateHelper $dateHelper )
{
$this->dateHelper = $dateHelper;
}
public function buildNews( $currentNews = null, $news)
{
if ( ! $currentNews) { // check if we already have the news stored
$currentNews = new News();
}
$currentNews->setNewsID( $news['NewsID'] );
$currentNews->setTitle( $news['Title'] );
$currentNews->setUpdated( $this->dateHelper->parseDate( $news['Updated'] ) );
$currentNews->setUrl( $news['Url'] );
$currentNews->setContent( $news['Content'] );
$currentNews->setSource( $news['Source'] );
$currentNews->setTermsOfUse( $news['TermsOfUse'] );
$currentNews->setTeam( $news['Team'] );
$currentNews->setPlayerID( $news['PlayerID'] );
return $currentNews;
}
}
this is used by NewsPersister
Class
Checks out my repo with a FindByOne()
passing id of the data I am processing.
namespace FantasyPro\DataBundle\Persisters;
use Doctrine\ORM\EntityManager;
use FantasyPro\DataBundle\Builder\NewsBuilder;
use FantasyPro\DataBundle\Entity\News;
class NewsPersister {
/**
* @var EntityManager $em
*/
private $em;
/**
* @var NewsBuilder $builder
*/
private $builder;
public function __construct( EntityManager $em, NewsBuilder $builder )
{
$this->em = $em;
$this->builder = $builder;
}
public function Persist($news){
//get the news repository
$repo = $this->em->getRepository( 'DataBundle:News' );
// get the current news from the db
$criteria = array(
'newsID' => $news['NewsID']
);
/**
* @var News $currentNews
*/
$currentNews = $repo->FindOneBy( $criteria );
//todo: use a logger to write this data to file
//build the news entity
$currentNews = $this->builder->buildNews( $currentNews, $news );
//persist the team
$this->em->persist( $currentNews );
}
}
My question answers: can drop the operator FindByOne()
and just use $em->merge()
instead$em->persist()
As I understand it, what $em->merge
sets the object to update or insert depending on whether the identifier exists or not? adding that he doesn't need my additional call?
source to share
no, you cannot delete
The difference is what you do with the entity after.
Persist takes an entity instance, adds it to the persistance context and manages it, so all other updates will be managed by the entity manager.
Merge will create a new entity instance, copy the object provided by the state form, and create a new managed copy, but the passed object will not be managed, so subsequent changes will not be checked out by the entity manager
In your example: if you change save to merge then it won't make any difference. Thus, the merge will do the same job as it would for the save. And usually you should use merge when you have a separate object or unserialized (like a cache)
source to share