Skip to content

Loading…

DDC-383: Setting Column name doesn't work predictably in associations #4678

Closed
doctrinebot opened this Issue · 12 comments

1 participant

@doctrinebot

Jira issue originally created by user kanundrum:

Setting a column name that is different from the property name yields errors in associations (e.g. in a one to one association I get "Undefined index: shipping_id in /var/www/wetawa/library/Doctrine/ORM/UnitOfWork.php on line 1782 Call ")

...
    /****
     * @Column(type="bigint", name="shipping_id")
     *
     * @var integer
     */
    protected $shippingId=0;
    /****
     * @OneToOne(targetEntity="Shipping")
     * @JoinColumn(name="shipping_id", referencedColumnName="id")
     * 
     * @var Shipping
     */
    protected $shipping;

The only way I've been able to get associations to work is by using the default naming so $shipping_id instead of $shippingId

@doctrinebot

Comment created by romanb:

Foreign keys (or discriminator columns) are not intended to be mapped to properties. What do you need $shippingId for?

@doctrinebot

Comment created by kanundrum:

I see your point though there might be some use cases for wanting to access $shippingId (maybe storing in some kind of log that doesn't need the full set of shipping info) and not incur the expense of getting the shipping object.

@doctrinebot

Comment created by @beberlei:

@akeem: This is possible without mapping the shipping-id, although its not recommended for the reason that you are depending on internal Doctrien 2 APIs. This should only be done as a very last resort (performance reasons).

You can retrieve the identifier of the shipping proxy object by calling:

$shippingId = $em->getUnitOfWork()->getEntityIdentifier($entity->shipping);

As another solution you could, if required for a specific use-case, retrieve only the shipping ids and initialize shipping as partial objects:

SELECT o, PARTIAL s.{id} FROM Order o JOIN o.shipping s
@doctrinebot

Comment created by romanb:

Let my try to clarify, because I saw you tweeting that you dislike this "limitation".

A foreign key has no meaning in an object model. Foreign keys are how relational databases establish associations/relations between rows. In object-oriented programming objects establish associations through object references. In a sense, when you map a foreign key to an object property you leak detail of your relational schema into your object model. Detail that is only ever relevant to a relational database. If you would ever persist this object in another type of persistent storage, the foreign key has no meaning. This level of abstraction that D2 provides is rare among PHP ORMs. Most require you to have foreign keys as properties which is a major flaw of the abstraction.

It should be possible to map foreign keys to properties but this has very low priority because even if you want to do it, it can only be a workaround and there are other ways that Benjamin pointed out.

That said, Doctrine does of course not "take away" access to the foreign keys. With array or scalar hydration or even plain SQL, of course, you can still get the foreign keys in a result but foreign keys have no place in an object model.

Just trying to communicate this better.

@doctrinebot

Comment created by kanundrum:

I appreciate the time spent on explaining this an do appreciate what you guys have said. I guess one of the things I really liked about the doctrine 2.0 direction was the use of plain php objects (so tempted to so pojos). While this is true there seem to be a number of caveats that get in the way of using those objects exactly how I want to (or in a way that isn't doctrine specific), so these caveats seem to make it a bit more intrusive than I initially thought (though less intrusive than having to extend classes). I'll chalk this one up to keep an eye on and I commend you guys on the work you've done so far.

@doctrinebot

Comment created by romanb:

Whenever you have questions on how to do something properly without dedicated foreign key properties just drop a mail to the user mailing list. For most cases there is a good solution and if not, we will create one.

@doctrinebot

Comment created by @beberlei:

This is not an issue. Closed

@doctrinebot

Issue was closed with resolution "Invalid"

@doctrinebot

Comment created by gedrox:

Still there is another issue related to this one.

When I create yaml files from existing database using the command line command "orm:convert-mapping --from-database yaml" the relational field "target_id" is created in both places - as a field and in the relation definition (under oneToOne in my case). Here I get the same problem as described above and the target object cannot be retrieved.

Sample generated yaml for city—country relation:

City:
  type: entity
  table: city
  fields:
    id:
      id: true
      type: integer
      unsigned: false
      nullable: false
      generator:
        strategy: IDENTITY
    countryId:
      type: string(2)
      fixed: true
      nullable: false
      column: country_id
    name:
      type: string(255)
      fixed: false
      nullable: true
  oneToOne:
    country:
      targetEntity: Country
      cascade: {  }
      mappedBy: null
      joinColumns:
        country_id:
          referencedColumnName: id
      orphanRemoval: false
  lifecycleCallbacks: {  }

This yaml causes problems when city is loaded.

Is it a bug or is it just me?

@doctrinebot

Comment created by gedrox:

The file attached is modified YAML export driver which workarounds the problem with the problem described in the previous comment.

Also it can append namespace to classes in the YAML files generated from the database schema.

Hope it helps someone.

@doctrinebot

Comment created by romanb:

This should be fixed now.

@doctrinebot doctrinebot added this to the 2.0-BETA4 milestone
@doctrinebot doctrinebot closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.