0

I'm working on a study project, implementing an ERP Webapplication with ZF2 and Doctrine.

Now I have a problem when I try to persist an entity.

It fails with this message: Catchable fatal error: Object of class Application\Entity\Scope could not be converted to string in ...\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 2791

I found a similar Question with this message, but the answer didn't help me: Doctrine: Object of class User could not be converted to string

I'm trying to persist the entity Product which has a relation to ScopedName and this entity has a relation to the Scope entity.

When I add a __toString() method to the Scope entity it saves everything correctly, so I'm guessing the problem is not in my form or controller. If my mapping are ok I would guess that its a Doctrine Bug that does not support composite primary keys correctly. As you can see below, my entity ScopedName has a composite key.

These are my relevant doctrine mappings

Scope

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name="Application\Entity\Scope" table="application_scope">      
        <id name="id" type="integer">
            <generator strategy="AUTO"/>
            <sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />            
        </id>
        <field name="code" type="string" />
        <unique-constraints>
            <unique-constraint columns="code" />
        </unique-constraints>                
    </entity>
</doctrine-mapping>

ScopedName

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="Catalog\Entity\Product\ScopedName" table="catalog_product_scoped_name">
        <id name="scope" column="scope_id" association-key="true" />        
        <id name="product" column="product_id" association-key="true" />                       
        <field name="value" type="string" />          
        <many-to-one field="scope" target-entity="Application\Entity\Scope">
            <join-column name="scope_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" nullable="false" />
            <cascade>
                <cascade-persist />
            </cascade>                                              
        </many-to-one>
        <many-to-one field="product" target-entity="Catalog\Entity\Product" inversed-by="scopedNames" nullable="false">
            <join-column name="product_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" />
            <cascade>
                <cascade-persist />
            </cascade>
        </many-to-one>
    </entity>
</doctrine-mapping>

Update

Is it maybe because I have no one-to-many in my Scope mapping? But I only need a unidirectional association here, because my Product entity will get more Associations like ScopedSku, ScopedDescription, ... and I don't want to define them all in my Scope mapping as this in another module and shouldn't know of all these ...

Update 2

Ok, I tried to add one-to-many to the other side, but didn't help either. Does someone have a clue why I get this error?

Community
  • 1
  • 1
ibo_s
  • 425
  • 4
  • 13

1 Answers1

0

Shame on myself. It was my own failure in my controller, sorry for this.

My editAction looks like this ... commented lines were causing this error

public function editAction() {                         
    $id = $this->params()->fromRoute('id');
    $form = $this->getServiceLocator()->get('FormElementManager')->get('\Catalog\Form\ProductForm');        
    $form->addAdditional();
    $product = $this->getEntityManager()->find('Catalog\Entity\Product', $id);
    $productOld = clone($product);                      
    $form->bind($product);
    if($this->request->isPost()) {
        $form->setData($this->request->getPost());

        if($form->isValid()) {
            foreach($product->getScopedNames() as $scopedName) {
                $scopedName->setProduct($product);
                //next line was the failure         
                //$scopedName->setScope($this->getEntityManager()->getReference('Application\Entity\Scope', $scopedName->getScope()));
                //$this->getEntityManager()->persist($scopedName);
            }
            foreach($productOld->getScopedNames() as $scopedName) {
                if(!$product->getScopedNames()->contains($scopedName)) {
                    $this->getEntityManager()->remove($scopedName);                       
                }
            }               
            $this->getEntityManager()->persist($product);
            $this->getEntityManager()->flush();
            $this->flashMessenger()->addSuccessMessage("Product has been saved successfully."); 
            $this->redirect()->toRoute('catalog/product');                                                           
        } else {
            $this->flashMessenger()->addErrorMessage("Form invalid");
        }               
    } else {
        $form->bind($product);
    }             

    return array(
        'form' => $form,
        'id' => $id
    );
}

I needed these lines before I made use of the DoctrineObject Hydrator. Now it works automatically. But I still need the line before and the next foreach in order to set the product itself to the relation and to remove old relations that aren't contained in the new post request.

Maybe someone has a better solution for this as well?

ibo_s
  • 425
  • 4
  • 13