Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 multiple mappedBy?

I've got a problem setting up the Doctrine mapping correctly.

I have a CashRegister Entity which has a bin location and a return bin location. Both locations are from the same Type (BinLocation Entity).

Outgoing from CashRegister, CashRegister->getBinLocations() and CashRegister->getReturnBinLocations() are working fine, but how can I achieve that BinLocation->getCashRegisters() returns all CashRegister Entities that are referenced (binLocation + returnBinLocation)?

/**
 * CashRegister
 *
 * @ORM\Table(name="cash_registers")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class CashRegister
{

    ...

    /**
     * @var BinLocation
     *
     * @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
     * @ORM\JoinColumn(name="bin_location_id", referencedColumnName="id")
     */
    private $binLocation;

    /**
     * @var BinLocation
     *
     * @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
     * @ORM\JoinColumn(name="return_bin_location_id", referencedColumnName="id")
     */
    private $returnBinLocation;


    /**
     * @return BinLocation
     */
    public function getBinLocation()
    {
        return $this->binLocation;
    }

    /**
     * @return BinLocation
     */
    public function getReturnBinLocation()
    {
        return $this->returnBinLocation;
    }

    ...

}

/**
 * BinLocation
 *
 * @ORM\Table(name="bin_locations")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class BinLocation
{

    ...

    /**
     * @var CashRegister[]
     *
     * @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation") <= Here is the problem, in this case mappedBy need to be an array [binLocation, returnBinLocation]
     */
    private $cashRegisters;


    /**
     * @return CashRegister[]
     */
    public function getCashRegisters()
    {
        return $this->cashRegisters;
    }

    ...

}
like image 485
ipsum Avatar asked Sep 28 '22 09:09

ipsum


1 Answers

The simple answer is that you cannot. mappedBy accepts only one argument.

The solution to achieve what you want is however simple. Create a second property in BinLocation called: cashRegisters2 as follows:

/**
 * @var CashRegister[]
 *
 * @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation")
 */
private $cashRegisters;

/**
 * @var CashRegister[]
 *
 * @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation") 
 */
private $cashRegisters2;

Then merge the Collections in your getCashRegisters method.

/**
 * @return CashRegister[]
 */
public function getCashRegisters()
{
    return new ArrayCollection(
                      array_merge($cashRegisters->toArray(), $cashRegisters2->toArray())
    );
}

Also change your CashRegister mappings accordingly:

/**
 * @var BinLocation
 *
 * @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
 * @ORM\JoinColumn(name="bin_location_id", referencedColumnName="id")
 */
private $binLocation;

/**
 * @var BinLocation
 *
 * @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters2")
 * @ORM\JoinColumn(name="return_bin_location_id", referencedColumnName="id")
 */
private $returnBinLocation;

Note: I did not test the code. This example is to server guide only.

Note2: The ArrayCollection merge was inspired from here: https://stackoverflow.com/a/16871539/2853903

like image 196
Mark Avatar answered Oct 03 '22 00:10

Mark