Annotation composed objected field is not inserted in database via Doctrine

Hi, I’ve got a form with annotations. The form fields are showing but somehow the data is not inserted in the database. There is no error when submitting the form either for the composed object. Only the data for the non-composed object/parent is inserted correctly.
The annotation form looks like below:

/**
 * @Annotation\Name("Post")
 * @Annotation\Hydrator("Laminas\Hydrator\ObjectPropertyHydrator")
 */

class Post
{
    /**
     * @Annotation\Exclude()
     */
    public $id;
    
    /**
     * @Annotation\Filter({"name":"StringTrim"})
     * @Annotation\Validator({"name":"StringLength", "options":{"min":5, "max":255}})
     * @Annotation\Attributes({"type":"text"})
     * @Annotation\Options({"label":"Title:"})
     */
    public $title;
    
    /**
     * @Annotation\Type("Laminas\Form\Element\Textarea")
     * @Annotation\Options({"label":"Description:"})
     */
    public $body;
    
    /**
     * @Annotation\Name("posts")
     * @Annotation\ComposedObject( {"target_object":"Post\Form\Annotation\Category", "is_collection":"true"} )
     */
    public $categories;

}

The post entity code looks like below:

/**
 * Post
 * 
 * @Gedmo\Loggable
 * @ORM\Table(
 *      name                = "posts",
 *      indexes = {
 * @ORM\Index(name="title_idx",        columns={"title"})
 *      }
 * )
 * @ORM\Entity(repositoryClass="Articles\Repository\PostRepository")
 */
class Post
{
    
    /**
     * @var integer
     *
     * @ORM\Column(type="integer", options={"unsigned"=true})
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var string
     *
     * @Gedmo\Versioned
     * @ORM\Column(type="string", length=255)
     */
    protected $title;

    /**
     * @var string
     *
     * @Gedmo\Versioned
     * @ORM\Column(type="text")
     */
    protected $body;

    /**
     * @var string
     *
     * @Gedmo\Versioned
     * @Gedmo\Slug(fields={"title"}, updatable=false)
     * @ORM\Column(type="string", length=255)
     */
    protected $slug;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="posts")
     * @ORM\JoinTable(
     *  name="post_category",
     *  joinColumns={
     * @ORM\JoinColumn(name="post_id", referencedColumnName="id")
     *  },
     *  inverseJoinColumns={
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     *  }
     * )
     */
    protected $categories;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->categories   = new ArrayCollection();
    }
    //...//
}

Thanks in advance!

Is the correct data present in the entities before they are inserted?

Yes, I can add/edit Post entity data but the composed object(Category) data is totally ignored. I can add/edit Category data via a single category form. But not having it as a composed object. Thanks!

Ignored by what? The form?

$form = (new Laminas\Form\Annotation\AnnotationBuilder)->createForm(Post::class);

$object = new Post();
$form->bind($object);

$form->setData(['…']);

if ($form->isValid()) {
    var_dump($object); // Is the correct data present here?
}

Hi @froschdesign,

I’ve created the form exactly as you’ve created it. The output for the Post Entity Object is like below.

object(Posts\Entity\Post)#575 (10) { ["id":protected]=> NULL ["title":protected]=> string(35) "Laminas Project community" ["body":protected]=> string(35) "Laminas Project community" ["slug":protected]=> NULL ["created_at":"Posts\Entity\Post":private]=> NULL ["updated_at":"Posts\Entity\Post":private]=> NULL ["categories":protected]=> object(Doctrine\Common\Collections\ArrayCollection)#569 (1) { ["elements":"Doctrine\Common\Collections\ArrayCollection":private]=> array(0) { } }  ["created_by":protected]=> NULL ["modified_by":protected]=> NULL }

Thanks!

Unfortunately, there is a misunderstanding here, because you should not rebuild the part from me, but you can say if your object is correctly filled with data at the point after validation.

I do not know your objects and have not looked at the annotation completely. But you will be able to tell by yourself if your object is correctly filled with the correct data at this point before it is processed further.

This allows us to further narrow down the circle of possible sources of error.

Thanks for the reply @froschdesign. The category object within Post Entity is empty. So, I’ve some mistake a mistake in the annotation? If that is the case I’ll dig it further. Thanks!

Is the title and the body set on your Post entity?


You define your form via annotations in a separate class but at the end the entity class must be filled with data.
Maybe I’m wrong here but how should the ObjectPropertyHydrator work for your Post entity here? See the documentation:

The ObjectPropertyHydrator hydrates objects and extracts data using publicly accessible properties which match a key in the data set.

Hi @froschdesign,
I’m using DoctrineORM, doctrine provides a doctrine hydrator which I used like below:

//Post:class is Post Annotation Form Class not Post Entity Class.
$form = (new Laminas\Form\Annotation\AnnotationBuilder)->createForm(Post::class);
$form->setHydrator(new \Doctrine\Laminas\Hydrator\DoctrineObject);

The form data is represented like below:

Thanks!

Your first post says something different, that’s why I asked.

In your form data you have Category but the related form element has the name posts?!

Hi @froschdesign, thanks for the reply. I think I’ve got a problem with my code. So, I’ll share it with you and let me know if I’m right or wrong.

  1. I’m creating my form from “Laminas\Form\Annotation\AnnotationBuilder”. Is that a correct thing to do when using doctrine? Because doctrine suggest using "\DoctrineORMModule\Form\Annotation\AnnotationBuilder($entityManager);"
  2. The second problem is that I’m trying to create an embedded form altogether rather than a select box for a category. Is that the reason the category field is getting neglected entirely?

The reason is when I created a form with doctrine, which came up with other issues and I couldn’t solve all of them. But, I was able to create a form. The form that doctrine annotation created was a form with category as a select box and it named the field categories as it is in post entity. But, my issue from start is to insert post data with a new category name. That means I’ve to create multiple category input boxes.

Thanks!