Doctrine2 Object Default for ManyToOne Relationship Property

I have a Doctrine2 object called "Order" that has several status properties. Valid status' are stored in another Entity, so a ManyToOne relationship is defined for those entities.

/**
 * @ORM\Entity()
 */
class Order extends AbstractEntity {
    // ...
    /**
     * @ORM\ManyToOne(targetEntity="Status")
     * @ORM\JoinColumn(onDelete="NO ACTION", nullable=false)
     */
    protected $status;

    /** @ORM\Column(nullable=true) */
    protected $stringProperty = "default value";

}

      

I need to set this state property to its default value when creating a new instance of the order object.

For the "non-relationship" property, I can just set it to the $ stringProperty above. But how do you do this for a relationship?

  • I am unable to set the id value of the corresponding entry as Doctrine2 will complain.
  • It is good if configured by default "Link" to the state object. The available status is' fixed and will not change (often).

How to set up an entity to set up the correct default relationship.

Preferably not in a listener when saving, as the status can be requested before.

+3


source to share


1 answer


There are several approaches, but I would suggest using OrderRepository as a factory to create new orders.

class OrderRepository
{
    public function create()
    {
        $order = new Order();
        $status = $this->_em->find('Status','default'); // or getReference
        $order->setStatus($status);
        return $order;
    }
}

// In a controller
$orderRepository = $this->container->get('order_repository');
$order = $orderRepository->create();

      

Once in the repository, you can initialize complex entity graphs that are ready to be persisted.

=============================================== === ========================

Plan B was to do this sort of thing on the order object and then use listeners to "fix the situation" before continuing or updating.



class Order
{
    public function __construct()
    {
        $this->status = new Status('Default');
    }
}

      

Of course the problem is that the default state object already exists in the database, so you get an error on failure. So you need to hang onFlush ( http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush ) listener in entity manager, check if the status object is being controlled by the object, and, if not, replace it with a managed object obtained from the Object Manager.

This approach allows you to deal with cleaner domain models without worrying about the level of persistence. On the other hand, dealing with a flush can be challenging. On the gripping hand, once you get it to work, it will open up some basic possibilities.

=============================================== === ======

There is also the question of what exactly the state object does. If all it contains is some kind of state ("entered", processed "), etc. Then you can think of it as a string. It looks like ROLE_USER objects.

+3


source







All Articles