orm: DDC-3480: ORM\Embeddable does not create ManyToOne column in the database

Jira issue originally created by user tvoslar:

Following Embeddable

/****
 * @ORM\Embeddable
 */
class Address
{
    /****
     * @ORM\ManyToOne(targetEntity="Country")
     */
    protected $country;

won’t save country attribute into the database table, other simple attributes (like type=“text”) saved normally.

    /****
     * @ORM\Embedded(class="LuciniLucini\Adsender\CommonBundle\Entity\Address")
     */
    private $address;

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 5
  • Comments: 56 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Comment created by @ocramius:

It will probably not implemented for now, as embeddables (in our vision) are fitting the use-case of ValueObjects. ValueObjects are (usually) supposed to be containing serializable data, and an entity reference is not serializable data.

For the reference, since @lcobucci and I spoke about this issue. Embeddables will be re-implemented, properly implemented. That should allow us to follow JPA 2.1, which states:

An embeddable class (including an embeddable class within another embeddable
class) may contain a collection of a basic type or other embeddable class.[16]

An embeddable class may contain a relationship to an entity or collection of
entities. Since instances of embeddable classes themselves have no persistent
identity, the relationship from the referenced entity is to the entity that
contains the embeddable instance(s) and not to the embeddable itself.[17] An
embeddable class that is used as an embedded id or as a map key must not contain
such a relationship.

I guess it’s retarded to not allow associations on embeddables just because for some it represents VO’s. If i want to use the VO concept on my project i simply won’t use associations on my embeddables. However if i want to use embeddables for other purposes such as split of concerns and composition of objects to avoid inheritance (as good oop practice). Doctrine is suposed to be a flexible framework and not stand in the way i want to design my project because of some extremist view. Every pattern depends on context and might not be the answer for every problem. The address and country is a clear case that the embeddables are not exclusively VO’s. And don’t forget @Ocramius, doctrine is not exactly a DDD implementation, its an ORM and its perfectly fine if people wants to use it without the DDD concept.

Breaking the relation by just replacing it with and integer is not terrible IMHO.

The case of the address embeddable class is very useful and most of the case, the country is a relation.

I understand the goal of value object, but if you are telling to save an ID, why not just tell the serializer to save the id of the relation?

In any case, the usage should be the concern of the developer IMHO.

@Ocramius Would you accept a PR integrating relation on embedded objects?

Comment created by eugene-d:

It will probably not implemented for now, as embeddables (in our vision) are fitting the use-case of ValueObjects. ValueObjects are (usually) supposed to be containing serializable data, and an entity reference is not serializable data.

This should be explicitly stated in the documentation.

Comment created by Yavin:

Hi, if is is not supported i think an exception should be thrown when someone use association in embedded class. Now it is just silently ommited.

I found code where embedded metadata is added: https://github.com/doctrine/doctrine2/blob/573153669c11a6f69201513831d3b8ce5e111d25/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L3200

Closing here meanwhile: if someone wants to take on the job of adding association mapping validation (preventing it, specifically) on metadata loading, feel free to do so.

Still actual in 2020

Since Embeddables is reserved to be VO. Why not create similar mechanism to allow required assotiations functionallity??

Any chance for embedded relations in 2016?

@Ocramius nope! Entities requires distinct table. But I mean just an object inside entity object, this object has relations with other entities. I need that decomposition because this nested object has special domain meaning and will be used-and-type hinted in some methods. Well, at this point it might be made as entity, but imagine if I need to do such decomposition many times for many entities - now I have to make one extra table and one more query for every usage. This not critical in my case but neither practical and optimal.

@Soullivaneuh no, I’ve been clear on that. The correct patch is #5809, but it is incomplete.

I mean by using EntityManager#find() or EntityRepository#find() instead of relying on lazy loading.

@Ocramius I completely agree with @Arkemlar. Embeddables is a fantastic feature but it breaks the object flow having to save foreign keys directly instead of using an association. Also, VO Embeddables could just as easily be called “entities” - they provide no additional functionality over entities, just clean and logical grouping. Even if the performance hit for a join that you mentioned above is trivial, it breaks my code design and logical grouping having to move related associations outside of the Embeddable, and that for me somewhat defeats the point of having them in the first place.

@Soullivaneuh storing the identifier is an acceptable solution. Loading the related entity would then require looping back to the ORM.

six years… good news. nothing changed!

@ryall unlikely: we are moving our focus to 3.x, where embeddables have been completely removed for now, and will need to be re-introduced/redesigned.

Still actual

up?

up ?

@Arkemlar Why would he agree to that if he won’t allow it in Embeddables? His decision to disallow associations seems to be somewhat unpopular. There’s also no good argument that I’ve heard about why this should be so.

Actually, it would be nicer and potentially solve this problem indirectly if Doctrine were made more modular and extensible which would allow us to then just replace the bits we want. Currently it’s quite difficult and often impossible to extend it without editing the source directly. I hope 3.0 will be more than just a few shiny new features - Doctrine needs a complete refactor IMO.

Do you realize that adding more associations on a large project mey represent a big performance hit? if i want to decompose my objects without affecting database performance on my projects i simply can’t? The hability to decompose objects while keeping a single table to avoid joins (and sometimes the responsability for hold some of the associations lies within those separeted objects) should not be restricted by the library. The correct use of VO’s should be the developer’s responsability. And i’m sorry for the “retarded” word, it wasn’t meant to offend you, it was to towards the idea in question and not you as a person. You are not retarded you are a very well respected professional and a really smart person.