3

I am working on a project that uses Docrtrine and Symfony 2.7. I have a Document entity that I want to clone, and I of course need to make sure that I don't have a duplicate primary key. Here is what I have attempted so far:

/**
 * Document
 *
 * @ORM\Table(name="documents")
 */
class Document {
    public function __clone(){
        $newObj = clone $this;
        $newObj->id = null;
        return $newObj;
    }
...
}

This does not seem to do much, however, as when I call clone myDocument and then try to persist, I still get this message:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'UNIQ_A2B07288ECC6147F'

How can I get my object's primary key to revert to a null or auto-incremented state?

=====

Upate: Using

public function __clone(){
    $this->id = null;
}

still results in the same error. Full error text:

An exception occurred while executing 'INSERT INTO documents (usageFrom, usageTo, status, workflow_identifier, created_date, modified_date, language_id, translationRoot_id, ownerGroup_id, responsibleUser_id, production_id, media_id, created_user, modified_user) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["2018-06-28 09:54:37", "2018-06-28 09:54:37", 100, "4cc723c2a5730c1b9c2ed6428ae57205", "2018-06-28 09:54:37", "2018-06-28 09:54:37", null, null, null, null, 1, null, 1, 1]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'UNIQ_A2B07288ECC6147F'

lxg
  • 12,375
  • 12
  • 51
  • 73
  • 2
    try with [detach](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#detaching-entities) or make a copy constructor (or check if [this answer](https://stackoverflow.com/a/186008/2270041) works for you) – Matteo Jun 28 '18 at 10:35

1 Answers1

7

This is not how PHP’s cloning works. Think of __clone like of __construct. In the __clone method, you must assign the new values to $this.

class Document 
{
    public function ___clone()
    {
        // simple as that
        $this->id = null;
    }
}

In your current code, the $newObj is going to be thrown away, while the cloned object still has the original ID.

Also, remember to clone child objects in your __clone method if you want to create a deep copy, otherwise you’ll end up with two entities referencing the same children. (Or, after persisting/reloading: One of the entities will have lost its children.)

lxg
  • 12,375
  • 12
  • 51
  • 73