I have a form with some nested fieldsets and upon persisting I receive the 
following error message:
 

Error message:


Additional information: 
Doctrine\ORM\ORMInvalidArgumentException File: Doctrine/ORM/
ORMInvalidArgumentException.php:91
 Message:
 A new entity was found through the relationship 'Entities\Product#type' 
that was not configured to cascade persist operations for entity: Entities\
Type@000000000c2f004400007ff44e874816. 

To solve this issue: Either explicitly call EntityManager#persist() on this 
unknown entity or configure cascade persist this association in the mapping 
for example @ManyToOne(..,cascade={"persist"}). If you cannot find out 
which entity causes the problem implement 'Entities\Type#__toString()' to 
get a clue.


I give the name of an existing entity so it should not see it as a new entity. 
Somewhere it was suggested that I need to pass the id, but looking at the 
official example it should be covered by the FieldSet and the DoctrineEntity.

I basically follow the main example given in hydrator.md

Could anyone help out?
 
CreateProductForm:

class CreateProductForm extends Form implements InputFilterProviderInterface
{

      public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('create-product-form');
        $this->setObjectManager($objectManager);

        $this->setHydrator(new DoctrineHydrator($this->getObjectManager()));

        $this->addElements();
    }

    public function addElements()
    {
        // Add the product fieldset, and set it as the base fieldset
        $productFieldset = new ProductFieldSet($this->getObjectManager());
        $productFieldset->setUseAsBaseFieldset(true);
        $this->add($productFieldset);
        
        
        // … add CSRF and submit elements …
        
    }
    

}


2 Sample Fieldsets:

class ProductFieldSet extends Fieldset implements 
InputFilterProviderInterface
{


    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('product');

        $this->setObjectManager($objectManager);


        $this->setHydrator(new DoctrineEntity($this->getObjectManager()))->
setObject(new Product());

        $this->addElements();
    }

    public function addElements()
    {
        $this->add(array(
            'name' => 'id',
            'type' => 'Hidden',
        ));

        $this->addLabelCode();
        $this->addArtist();
        $this->addTitle();
        $this->addDescription();
        $this->addPrice();
        $this->addHints();
        $this->addType();
    }

// A lot of add methods
     /**
     * Add Type to the Cms\Form\ProductFieldSet
     */
    private function addType()
    {
        $typeFieldset = new TypeFieldSet($this->getObjectManager());
        $typeFieldset->setName('type');
//        $labelFieldset->setAttribute('required', TRUE);
//        $labelFieldset->setAttribute('class', 'form-control');

        $typeFieldset->setLabel('Type');
//        $labelFieldset->setLabelAttributes(array('class' => 
'control-label'));

        $this->add($typeFieldset);
    }

}




Related Type Fieldset:

class TypeFieldSet extends Fieldset implements InputFilterProviderInterface
{

    

    /**
     * Construct Cms\Form\GenreFieldSet.
     * 
     * @param ObjectManager $objectManager
     */
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('type');

        $this->setObjectManager($objectManager);

        $this->setHydrator(new DoctrineEntity($this->getObjectManager()))->
setObject(new Type());

        $this->addElements();
    }

    /**
     * Method responsible for adding elements to \Cms\Form\Fieldset.
     */
    public function addElements()
    {
        $this->add(array(
            'type' => 'Zend\Form\Element\Hidden',
            'name' => 'id'
        ));

        $this->add(array(
            'name' => 'name',
            'type' => 'Zend\Form\Element\Text',
            'attributes' => array(
                'required' => true,
                'id' => 'name',
                'class' => 'form-control',
                'placeholder' => 'Enter type name'
            ),
            'options' => array(
                'label' => 'Name',
                'label_attributes' => array(
                    'class' => 'control-label'
                ),
            ),
        ));
    }



ProductController:

/**
     * Add a new Entities\Product
     * 
     * @return type
     */
    public function addAction()
    {
        // Get your ObjectManager from the ServiceManager
        $objectManager = $this->getServiceLocator()->get(
'Doctrine\ORM\EntityManager');

        // Create the form and inject the ObjectManager
        $form = new CreateProductForm($objectManager);

        // Create a new, empty entity and bind it to the form
        $product = new Product();
        $form->bind($product);

        if ($this->request->isPost())
        {
            $form->setData($this->request->getPost());

            if ($form->isValid())
            {
                $createAnother = (boolean) $this->request->getPost(
'create_another_product');

                $product->setInstockdate(new DateTime());
                $this->getProductService()->saveProduct($product);

                $this->flashMessenger()->addSuccessMessage('Product ' . 
$product->getName() . ' saved');

                // In case create_another is true redirect to add action
                if ($createAnother)
                {
                    $options = array("query" => array("createAnother" => 
TRUE));
                    $this->redirect()->toRoute('product', array('action' => 
'add'), $options);
                }
                else
                {
                    return $this->redirect()->toRoute('product');
                }
            }
            else
            {
                $this->flashMessenger()->addErrorMessage($form->getMessages
());
            }
        }

        // After redirect in case create_another is true set the related 
form variable to true
        if ($this->params()->fromQuery('createAnother'))
        {
            $form->get('create_another_product')->setValue(TRUE);
        }

        $csvLabels = $this->getLabelService()->getImplodedLabels();
        return new ViewModel(array(
            'product' => $product,
            'csvLabels' => $csvLabels,
            'form' => $form
        ));
    }

Doctrine Entities:

Product (showing only relevant snippet)

/**
 * Product
 *
 * @ORM\Table(name="products")
 * @ORM\Entity(repositoryClass="\Entities\ProductRepository")
 */
class Product
{
/**
     * @var \Entities\Type
     *
     * @ORM\ManyToOne(targetEntity="Entities\Type")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="type_id", referencedColumnName="id", 
nullable=false)
     * })
     */
    private $type;
}

View: (only relevant snippets)
<?php
$form->setAttribute('action', $this->url('product', array('action' => 'add'
)));
$form->setAttribute('class', 'form-horizontal');

$form->prepare();
echo $this->form()->openTag($form);

$product = $form->get('product');
$type = $product->get('type');
?>

<div class="form-group <?= ($this->formElementErrors($type->get('name'))) ? 
'has-error' : ''; ?>">
    <?php echo $this->formHidden($type->get('id')); ?>
    <?php
    echo $this->formRow($type->get('name')) . PHP_EOL;
    ?>
</div>

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to