Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine - Store ArrayCollection keys

Whenever I use an ArrayCollection with Doctrine ORM (2.3, PHP > 5.4), and associate the object values with a key in the collection (such as when using the set method), the values get stored correctly in the database. But when I want to retrieve the collection from the entity, the keys don't get retrieved and instead they use a numeric index.

For instance, if I have the following classes:

/** @Entity */
class MyEntity
{
    /** @OneToMany(targetEntity="MyOtherEntity", mappedBy="mainEntity") */
    private $myArray;

    public function __construct()
    {
        $this->myArray = new ArrayCollection();
    }

    public function addOtherEntity($key, $value)
    {
        $this->myArray->set($key, $value);
    }

    ...
}

/** @Entity */
class MyOtherEntity
{
    /** @ManyToOne(targetEntity="MyEntity", inversedBy="myArray") */
    private $mainEntity;
    ...
}

The set method works properly, but when I retrieve the information the keys in $myArray are gone.

How do I make the ORM remember properly the keys? Thank you beforehand.

like image 809
Carlos Vergara Avatar asked Jun 25 '13 17:06

Carlos Vergara


People also ask

How to sort an existing collection in a repository?

To sort an existing Collection you are looking for the ArrayCollection::getIterator () method which returns an ArrayIterator. example: The easiest way would be letting the query in the repository handle your sorting.

How to order by a property in doctrine criteria?

Doctrine criteria does not allow to order by a property on a related object. If you want to do it (like me), you have to use the uasort method of the Iterator like a previous response and if you use PHP 7, you can use the Spaceship operator <=> like this : Show activity on this post.

Is there a way to order arraycollection by end date?

If you have an ArrayCollection field you could order with annotations. eg: Say an Entity named Society has many Licenses. You could use That will order the ArrayCollection by endDate (datetime field) in desc order.


1 Answers

This is solved in the following way:

/** @Entity */
class MyEntity
{
    /** @OneToMany(targetEntity="MyOtherEntity", mappedBy="mainEntity", indexBy="key") */
    private $myArray;

    public function __construct()
    {
        $this->myArray = new ArrayCollection();
    }

    public function addOtherEntity($key, $value)
    {
        $this->myArray->set($key, $value);
    }

    ...
}

/** @Entity */
class MyOtherEntity
{
    /** @ManyToOne(targetEntity="MyEntity", inversedBy="myArray") */
    private $mainEntity;

    /** @Column(name="MyOtherTable_Key", type="string", unique=true, length=50)
    private $key;
    ...
}

You also need MyOtherTable_Key in your db schema so it can store the key properly.

Remember to always set the object key into the property. One way to do so is to declare the key in the constructor.

public function __construct($key)
{
    $this->key = $key;
}
like image 83
Carlos Vergara Avatar answered Oct 24 '22 10:10

Carlos Vergara