0

Iterations of this question have been asked in the past, but this presents unique challenges as it combines some of the issues in one larger problem.

I have an entity(User) that is used as the user class in my application, then I have another entity (UserExtra), in a one-to-one relationship with the user entity, UserExtra's id is the same as User. The foreign key is the same as the primary key.

When the user object is loaded (say by $this->getUser() or by {{ app.user }}, the UserExtra data is also loaded through a join. The whole point of having two entities is so I don't have to load all the data at once.

I even tried defining a custom UserLoaderInterface/UserProviderInterface Repository for User, making sure that refreshUser and loadUserByUsername would only load the User data (I'd like for the UserExtra data to sit in a proxy unless I explicitly need it) but when Doctrine goes to Hydrate the object, it issues an extra query to load the UserExtra data, thereby skipping the Proxy status.

Is there a way out of this?

miltone
  • 4,416
  • 11
  • 42
  • 76
ABM_Dan
  • 238
  • 4
  • 14
  • So far I managed to make it work by improperly marking the relationship as a many-to-one (extra being many) and modifying getExtra and setExtra so that they access ->extra[0]. This is of course bad. – ABM_Dan Feb 29 '16 at 22:24

1 Answers1

0

there are many solution for your issue:

1) Change the owning side and inverse side http://developer.happyr.com/choose-owning-side-in-onetoone-relation - I don't think that's right from a DB design perspective every time.

2) In functions like find, findAll, etc, the inverse side in OneToOne is joined automatically (it's always like fetch EAGER). But in DQL, it's not working like fetch EAGER and that costs the additional queries. Possible solution is every time to join with the inverse entity

3) If an alternative result format (i.e. getArrayResult()) is sufficient for some use-cases, that could also avoid this problem.

4) Change inverse side to be OneToMany - just looks wrong, maybe could be a temporary workaround.

5) Force partial objects. No additional queries but also no lazy-loading: $query->setHint (Query::HINT_FORCE_PARTIAL_LOAD, true) - seams to me the only possible solution, but not without a price: Partial Objects are a little bit risky, because your entity behavior is not normal. For example if you not specify in ->select() all associations that you will user you can have an error because your object will not be full, all not specifically selected associations will be null

6) Not mapping the inverse bi-directional OneToOne association and either use an explicit service or a more active record approach - https://github.com/doctrine/doctrine2/pull/970#issuecomment-38383961 - And it looks like Doctrine closed the issue

this question may help you : one to one relation load

Community
  • 1
  • 1
CodeIsLife
  • 1,205
  • 8
  • 14
  • Approach 4 seems to be the only one who's fitting the solution (as I mentioned in my previous comment). Doctrine users have brought up this issue several times. Suggesting things like lazy loading of non-entities attributes (like load a user object, but use a proxy field for the "preferredCookieType" attribute, and issue another query when that value is actually accessed). But I think it remains an open issue. – ABM_Dan Mar 03 '16 at 15:53