How to re-save the entity as another row in Doctrine 2
Try cloning and add the following method to your entity
public function __clone() {
$this->id = null;
}
You may need to detach the entity before persisting it. I don't have my dev machine handy to test this right now.
$f = clone $e;
$em->detach($f);
$em->persist($f);
$em->flush();
Update
Just tried using a simple SQLite demo. You shouldn't need to do anything. The following worked for me without adding a __clone()
method or doing anything else out of the ordinary
$new = clone $old;
$em->persist($new);
$em->flush();
Once flushed, the $new
entity had a new ID and was saved as a new row in the DB.
I would still null the ID property via the __clone()
method as it makes sense from a pure model view.
Update 2
Digging into the Doctrine code, this is because the generated proxy classes implement __clone()
with this important line
unset($this->_entityPersister, $this->_identifier);
Symfony2/Doctrine: How to re-save an entity with a OneToMany as a cascading new row
The thing with clone
is...
When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.
If you are using Doctrine >= 2.0.2, you can implement your own custom __clone() method:
public function __clone() {
// Get current collection
$pupils = $this->getPupils();
$this->pupils = new ArrayCollection();
foreach ($pupils as $pupil) {
$clonePupil = clone $pupil;
$this->pupils->add($clonePupil);
$clonePupil->setClassroom($this);
}
}
NOTE: before Doctrine 2.0.2 you cannot implement a __clone()
method in your entity as the generated proxy class implements its own __clone()
which does not check for or call parent::__clone()
. So you'll have to make a separate method for that like clonePupils()
(in Classroom
) instead and call that after you clone the entity. Either way, you can use the same code inside your __clone()
or clonePupils()
methods.
When you clone your parent class, this function will create a new collection full of child object clones as well.
$cloneClassroom = clone $classroom;
$cloneClassroom->clonePupils();
$em->persist($cloneClassroom);
$em->flush();
You'll probably want to cascade persist on your $pupils
collection to make persisting easier, eg
/**
* @ORM\OneToMany(targetEntity="Pupil", mappedBy="classroom", cascade={"persist"})
*/
protected $pupils;
Doctrine 2 update from entity
I had to use
$entityManager->merge($data)
Symfony2 - Doctrine - Is there any way to save entity in one line?
Well persist()
and flush()
are totally different and independent operation. When you persist an entity object you are telling the entity manager to track changes of the object. When you call flush()
method the entity manager will push the changes of the entity objects the entity manager tracks to the database in single transaction. Most of the time entity manager have to manage multiple object. For example besides your product
entity you may also have to track tag
or cart
entity. Calling persistAndFlush()
every time when you save those entity object will cause multiple IO connection to DB. Which is not efficient. So I think it is better to treat them as a separate operation.
Doctrine get objects, manipulate data and insert as new rows
Just using PHP's clone is sufficient to duplicate an entity as a new row
$newEntity = clone $alreadyPersistedEntity;
// Manipulate $newEntity as desired
$em->persist($newEntity);
$em->flush();
How to save row order which is pointed in IN() expression?
You're not using ORDER BY
clause at all. Putting additional field in SELECT
clause won't change order.WHy would it?
Try to use orderBy
instead of addSelect
.
$qb = $this->createQueryBuilder('v');
$qb
->select('v')
->andWhere('v.id IN(:vehicles)')
->setParameter('vehicles', $vehiclesArr)
->orderBy("FIND_IN_SET(v.id, '$vehiclesStr')", 'ASC');
;
return $qb->getQuery()->getResult();
Assuming $vehiclesStr
has correct value of course.
Doctrine saves entities twice
You have configured the cascade={"persist"}
option for the relation which means Doctrine will save "new" entities found through the relation.
As your question suggests the createdBy
field can only contain a relationship to already existing users. This means cascade
is definitely not necessary here. It's also the reason why existing entities are persisted again in your case.
Remove the cascade
option from the mapping-configuration for the property to resolve your issue.
Clear your cache afterwards.
Related Topics
How to Resolve "Must Be an Instance of String, String Given" Prior to PHP 7
How to Password Protect Folder/Page Using PHP Without a Db or Username
PHP Conditionals, Brackets Needed
How to Pass an Array via $_Get in PHP
Namespace in PHP Codeigniter Framework
Ajax Call with Contenttype: 'Application/JSON' Not Working
Storing Arrays in the Database
How to Connect to MySQL Database in PHP Using MySQLi Extension
Simple PHP Contact Form with Firebase Hosting
Creating Anonymous Objects in PHP
Detecting Image Type from Base64 String in PHP
How to Get the Unicode Value of a Character or Vise Versa with PHP