Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-38

associations that are null should not create a prox object

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-ALPHA2
    • Fix Version/s: 2.0-ALPHA3
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      Associations that are nullable do not work as expected. When the association is null, i.e. the id in the database is null, the association is not null when loaded from the database. Doctrine creates a proxy object for the association that, when loaded, has no values for any fields. Doctrine should check during object hydration if the association is null. If true then no proxy object should be created. Please see DDC-34 for my schema.

        Activity

        Hide
        Roman S. Borschel added a comment -

        Yea, I know this issue and it needs to be corrected. When an association is optional (i.e. can be null) the fetch strategy must default to EAGER, instead of LAZY. That means even if the assocition is not joined, a separate select is issued because without fetching the association, you dont know whether null means "not fetched" or "no association". Optional associations simply can not be lazy.

        Show
        Roman S. Borschel added a comment - Yea, I know this issue and it needs to be corrected. When an association is optional (i.e. can be null) the fetch strategy must default to EAGER, instead of LAZY. That means even if the assocition is not joined, a separate select is issued because without fetching the association, you dont know whether null means "not fetched" or "no association". Optional associations simply can not be lazy.
        Hide
        Roman S. Borschel added a comment -

        Small correction: Optional, single-valued associations can not be lazy.

        Show
        Roman S. Borschel added a comment - Small correction: Optional, single-valued associations can not be lazy.
        Hide
        Ismo Toijala added a comment -

        If I have understood this correctly, making an association eagerly loaded means that it will always be loaded with the other end of the association. The eager associations that the first association has will also be loaded, etc. This means that, in a schema in which a user has an association to its creator, possibly very many users will be loaded if one is loaded.

        Loading only the one eager association is not a problem. Loading the eager associations of the association and so on is a problem. Would it be possible to add an option on optional associations to always load the id from the database to see if it is null. If it is null, we now know that no proxy object is needed. If it is not null, we create a proxy object that loads the entity lazily.

        This would mean that loading one user would not result in possibly many users being loaded, but only the originally loaded user. Accessing the creator would load it, like now. I am not sure about the performance impacts of this feature, but it should be better than eagerly loading the associations. I am also not sure if an additional select statement must be issued. Couldn't all queries automatically by default load the ids of the associations id the hydration mode is object?

        Show
        Ismo Toijala added a comment - If I have understood this correctly, making an association eagerly loaded means that it will always be loaded with the other end of the association. The eager associations that the first association has will also be loaded, etc. This means that, in a schema in which a user has an association to its creator, possibly very many users will be loaded if one is loaded. Loading only the one eager association is not a problem. Loading the eager associations of the association and so on is a problem. Would it be possible to add an option on optional associations to always load the id from the database to see if it is null. If it is null, we now know that no proxy object is needed. If it is not null, we create a proxy object that loads the entity lazily. This would mean that loading one user would not result in possibly many users being loaded, but only the originally loaded user. Accessing the creator would load it, like now. I am not sure about the performance impacts of this feature, but it should be better than eagerly loading the associations. I am also not sure if an additional select statement must be issued. Couldn't all queries automatically by default load the ids of the associations id the hydration mode is object?
        Hide
        Roman S. Borschel added a comment -

        Yes, I think an optimization like this might be possible but its certainly non-trivial. So an optional single-valued association configured LAZY would mean that you get either NULL or an uninitialized proxy object. The EAGER loading needs improvements anyway. Thanks for the suggestion.

        Of course, if you happen to have a patch already I will happily look at it

        Show
        Roman S. Borschel added a comment - Yes, I think an optimization like this might be possible but its certainly non-trivial. So an optional single-valued association configured LAZY would mean that you get either NULL or an uninitialized proxy object. The EAGER loading needs improvements anyway. Thanks for the suggestion. Of course, if you happen to have a patch already I will happily look at it
        Hide
        Roman S. Borschel added a comment -

        This behavior is now fixed in the best way currently possible.

        Owning sides of a one-one association will always select the foreign key, so if the associated entity is not fetch-joined, it gets either a proxy or null.

        But inverse sides of one-one associations can never be lazy.

        Imagine:

        User <-> Address (one-one, Address owning side with user_id)

        When only a User is loaded, we dont know whether the address is null or not and consequently whether we can use a proxy or not.
        We would in any way either need a join or a separate select and both ways, we can just get the real object anyway if we're already forced to go to the database.

        For the owning side of a one-one this is easier! Since the foreign key is there we know what to do.

        This is the best behavior I can offer right now and I've checked back with some of my Hibernate projects and they work the same.

        Show
        Roman S. Borschel added a comment - This behavior is now fixed in the best way currently possible. Owning sides of a one-one association will always select the foreign key, so if the associated entity is not fetch-joined, it gets either a proxy or null. But inverse sides of one-one associations can never be lazy . Imagine: User <-> Address (one-one, Address owning side with user_id) When only a User is loaded, we dont know whether the address is null or not and consequently whether we can use a proxy or not. We would in any way either need a join or a separate select and both ways, we can just get the real object anyway if we're already forced to go to the database. For the owning side of a one-one this is easier! Since the foreign key is there we know what to do. This is the best behavior I can offer right now and I've checked back with some of my Hibernate projects and they work the same.

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Ismo Toijala
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: