I'm trying to build a proper CRUD module for Magento 2.
My module contains for now an entity called Author.
This module contains the main entity table and a many to many relations table with the store views (similar to the cms pages and static blocks).
I've created, among others, an interface for the main model called [Namespace]\[Module]\Api\Data\AuthorInterface following the same guidelines as for CMS pages.

interface AuthorInterface extends ExtensibleDataInterface
     const AUTHOR_ID    = 'author_id';
     const NAME         = 'name';
     const STORE_ID     = 'store_id'; //this is missing in the cms page interface
     * Get ID
     * @return int|null
    public function getId();

     * Get name
     * @return string
    public function getName();
     * set id
     * @param $id
     * @return AuthorInterface
    public function setId($id);

     * set name
     * @param $name
     * @return AuthorInterface
    public function setName($name);
     * @param $storeId
     * @return AuthorInterface
    public function setStoreId($storeId);

     * @return array
    public function getStoreId();

Now here come the differences and problems.
The cms page interface does not contain the constant STORE_ID nor the methods setStoreId or getStoreId.
But from my point of view they should be there.
Also the cms pages save action uses the $page->save() call that is deprecated.
I decided to use repositories.
So my save action looks something like this:

$data = $this->getRequest()->getPostValue();
$author->setName($data['name']);//don't worry, I have a verification for the existence of $data['name']
$this->authorRepository->save($author); //authorRepository is an instance of \[Namespace]\[Module]\Api\AuthorRepositoryInterface

This works nicely, but what if my entity has a lot of fields, not just a name?
I don't want to call ->set... a hundred times. Plus, if I add one more field, I need to modify my code.
I discovered the method \Magento\Framework\Api\DataObjectHelper::populateWithArray.
Now I can simply call

$this->dataObjectHelper->populateWithArray($author, $data , '\[Namespace]\[Module]\Api\Data\AuthorInterface'); //where dataObjectHelper is an instance of \Magento\Framework\Api\DataObjectHelper  

This, again, works flawlessly except for the store_id.
I get an exception Class array does not exist because the annotation for getStoreId says @return array. can confirm that changing this annotation changes the exception message or works when changing the return type to string. But my store id is going to be an array not a string.

What is the proper way to handle this kind of case?

I could go around this by using

$data = $this->getRequest()->getPostValue();
if (isset($data['store_id'])) {
$this->dataObjectHelper->populateWithArray($author, $data , '\[Namespace]\[Module]\Api\Data\AuthorInterface'); 

But this looks dirty.

  • Are getStoreId return array? 8|
    – KAndy
    Jun 14, 2016 at 18:54
  • Yes, getStoreId will return an array. The ids of the stores associated to my entity.
    – Marius
    Jun 14, 2016 at 19:15

1 Answer 1


Magento service layers support only homogeneous arrays.

So you cannot define type as just array. You should define it as TypeName[], for example int[].


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.