api-platform / core

The server component of API Platform: hypermedia and GraphQL APIs in minutes
https://api-platform.com
MIT License
2.44k stars 868 forks source link

Associations initialized as array instead of ArrayCollection #152

Closed Drachenkaetzchen closed 8 years ago

Drachenkaetzchen commented 9 years ago

I'm trying to implement an event listener as per documentation. The Doctrine documentation states that associations should be initialized, and they use an ArrayCollection as default. In my project, this is exactly the same, and I expect that the return value of my getter is always of the ArrayCollection class.

It seems that DunglasAPIBundle deserializes associations as array, not as ArrayCollection. Thus I can't use the ArrayCollection´ methods in the event listener, because a call to my getter returns anarrayinstead of anArrayCollection`.

Drachenkaetzchen commented 9 years ago

Clarification: What I'm trying to achieve is to add or remove entities from the collection after deserializing. I tried using the getter, modifying the array, then calling the setter, but this results in the new entity in the association having a NULL reference.

dunglas commented 9 years ago

Does your entity have a setter or only adder/remover? As a workaround I think that the PropertyAccess component will not override the default type when using adder/remover method.

Another workaround is to test the type of the parameter is the setter and to instatiate an ArrayCollection from the array.

Drachenkaetzchen commented 9 years ago

I have solved part of this issue. One issue being that when adding/deleting items manually, I forgot to set the association on the inverse side.

The other issue being that no ArrayCollection or: PersistentCollection is returned.

I would expect that I would be able to trust that my entity class returns the proper type and not an array. Of course, your workaround works, however, I feel that this should be solved by DunglasApiBundle.

The root cause can be found in https://github.com/dunglas/DunglasApiBundle/blob/master/JsonLd/Serializer/ItemNormalizer.php#L246 where the collection is always initialized as an empty array.

I'm not sure what the best approach would be, because we don't know what the users preference is. Of course array is the lowest common denominator. One thing that could be done is to call the getter of the attribute and see if it's an instance of the Collection Interface. If so, all operations should take place on that collection. To make denormalizing easier, the collection could be cleared after retrieval from the getter. However, I'm not certain of any side effects, especially with the PersistentCollection.

dunglas commented 9 years ago

I'll investigate about that. Does it works if you comment the setter but letter the adder and the remover?

Drachenkaetzchen commented 9 years ago

No, I receive an error that no setter is configured. I guess this issue is related to #153.

dunglas commented 9 years ago

The problem is related to Doctrine internals. I've opened a PR on PartKeepr with a workaround: partkeepr/PartKeepr#409. Let me know if you think it's OK to close this bug.