I'm trying to save in cascade some object and retrieve it. I have 3 Object over 3 entities.
Entites:
class Order
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var object $basket
*
* @ORM\OneToOne(targetEntity="Entity\Basket", inversedBy="order")
*/
protected $basket;
...
}
class Basket
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var array $declinations
*
* @ORM\OneToMany(targetEntity="Entity\BasketDeclination", mappedBy="basket")
*/
protected $declinations;
/**
* Order owner (reversed side)
*
* @var OrderClient $order
*
* @ORM\OneToOne(targetEntity="Entity\Order", mappedBy="basket")
*/
protected $order;
...
}
class BasketDeclination
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var integer $basket
*
* @ORM\ManyToOne(targetEntity="Entity\Basket", inversedBy="declinations")
*/
protected $basket;
...
}
Object Over Entity:
class OrderObject
{
function __construct(
EntityManager $em,
Order $entity = null,
BasketObject $basket = null
)
{
$this->em = $em;
if (!$entity) {
$this->entity = new Order();
$this->basket = $basket;
} else {
$this->setDataFromEntity($entity);
}
}
protected function setDataFromEntity(Order $entity)
{
$basketFactory = new BasketFactory($this->em);
$this->entity = $entity;
$this->basket = $basketFactory->getBasket($entity->getBasket()->getId());
}
public function save($flush = false)
{
// save subObject
$this->basket->save();
// set link
$this->entity->setBasket($this->basket->getEntity());
$this->em->persist($this->entity);
if ($flush) {
$this->em->flush();
}
}
public function refresh()
{
$this->em->refresh($this->entity);
$this->setDataFromEntity($this->entity);
}
...
}
class BasketObject
{
function __construct(EntityManager $em, Basket $entity = null)
{
$this->em = $em;
if (!$entity) {
$this->entity = new Basket();
$this->declinations = array();
} else {
$this->setDataFromEntity($entity);
}
}
protected function setDataFromEntity(Basket $entity)
{
$this->entity = $entity;
$this->declinations = array();
foreach ($entity->getDeclinations() as $declination) {
$this->declinations[] = new BasketDeclinationObject($this->em, $declination);
}
}
public function save($flush = false)
{
foreach ($this->declinations as $declination) {
$declination->save();
}
$this->em->persist($this->entity);
if ($flush) {
$this->em->flush();
}
}
...
}
class BasketDeclinationObject
{
public function __construct(
EntityManager $em,
BasketDeclination $entity= null,
BasketObject $basket = null)
{
$this->em = $em;
if (!$entity) {
$this->entity = new BasketDeclination();
$this->basket = $basket;
} else {
$this->setDataFromEntity($entity);
}
}
protected function setDataFromEntity(BasketDeclination $entity)
{
$this->entity = $entity;
$declinationFactory = new DeclinationFactory($this->em);
$this->declination = $declinationFactory->getDeclination($entity->getDeclination()->getId());
}
public function save($flush = false)
{
if ($this->quantity <= 0) {
$this->em->remove($this->entity);
$this->remove = true;
return ;
}
if (!$this->entity->getId()) {
$this->entity->setBasket($this->basket->getEntity());
}
$this->entity->setQuantity($this->quantity);
$this->em->persist($this->entity);
if ($flush) {
$this->em->flush();
}
}
...
}
The problem is that in my test when I try for a basket to add BasketDeclination then save the Basket is saved and BasketDeclination too. Then when I $basket->refresh() the basket is refresh and the BasketDeclinaiton is rebuild from entity
BUT when I have an order whith a basket and I add BasketDeclinaiton ($order->basket->addDeclination(...)) When I save all entities are saved then when I refresh the order I get back the order and the basket. but the entity $basket->getDeclinations() does not have any thing
What I am doing wrong?
If the problem is indeed that the entity manager is not refresh
ing associations (as suggested by Mohammad AbuShady), the answer to tell your entities to cascade the refresh
operation.
class Basket
{
// ...
/**
* @var array $declinations
*
* @ORM\OneToMany(
* targetEntity="Entity\BasketDeclination",
* mappedBy="basket",
* cascade={"refresh"} // THIS LINE ADDED
* )
*/
protected $declinations;
// ...
...
}
I will go with two guesses:
You should use the cascade annotation to the classes to allow cascade "persist" and probably cascade "refresh" too. As stated on the documentation. Something like:
@ORM\OneToOne(targetEntity="Entity\Order", mappedBy="basket", cascade={"persist", "remove", "refresh"})
You are missing a persist()
or a flush()
on the Declinations before refreshing. If you are not cascading you need to call them on each object you want to keep and THEN call the refresh()
method.
(It's always a good idea too to check that your proxies are created and working all right when you work with nested objects)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With