How to Re-Save the Entity as Another Row in Doctrine 2

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



Leave a reply



Submit