Viewed   86 times

Let's say I have entity $e. Is there any generic way to store it as another row, which would have the same entity data but another primary key?

Why I need this: I'm implementing some sort of Temporal Database schema and instead of updating the row I just need to create another one.

 Answers

5

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);
Saturday, September 10, 2022
2

Your abstract base class has to be anotated as Mapped Superclasses and include the HasLifecycleCallbacks-Annotation.

Further Information: Inheritance Mapping in the Doctrine Documentation.

/**
 * @ORMMappedSuperclass
 * @ORMHasLifecycleCallbacks
 */
abstract class AbstractBase
{
    [...]

    /**
     * @ORMPreUpdate
     */
    public function setUpdatedAt()
    {
        $this->updatedAt = new DateTime();
    }
}

/**
 * @ORMEntity(repositoryClass="EntityRepositoryUserRepository")
 * @ORMTable(name="users")
 */
class User extends AbstractBase
{
    // some fields, relations and setters/getters defined here, these all work as expected.
}
Thursday, October 6, 2022
 
joulss
 
3

See Serializing Entities in doctrine manual: (Everything you save in a session is serialized and deserialized.)

Serializing entities can be problematic and is not really recommended, at least not as long as an entity instance still holds references to proxy objects or is still managed by an EntityManager.

There is a technical limitation that avoid private properties from being serialized when an entity is proxied (lazy-loaded entities are proxied).

This means that you have to avoid using private properties for the entities you want to serialize (use protected entities instead).

Also, if a lazy-loaded entity is not loaded at serialization time, it won't be loadable after de-serialization. So you have to make sure the entity is fully loaded before serializing it.

Sunday, November 20, 2022
 
4

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

/**
 * @ORMOneToMany(targetEntity="Pupil", mappedBy="classroom", cascade={"persist"})
 */
protected $pupils;
Sunday, November 20, 2022
 
4

works fine for me

resources.doctrine.dbal.connections.default.parameters.driverOptions.1002 = "SET NAMES 'UTF8'"

1002 is the integer value of PDO::MYSQL_ATTR_INIT_COMMAND:

Command to execute when connecting to the MySQL server. Will automatically be re-executed when reconnecting. Note, this constant can only be used in the driver_options array when constructing a new database handle.

Saturday, December 3, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :