1

I have an entity, say A. And another one B.

A={id,name} B={id,details}

I want a one-to-one relation. Basically for each x from A there must be exactly one y from B and the reverse. So I thought about solutions and came up with the following.

1. The id is shared.

But then basically it will be like. A={same_id,name} B={same_id,details} same_id is unique

  • B will have a foreign key for same_id to A.same_id.
  • Or A will have a foreign key for same_id to B.same_id

But I want to be able to get the details from A. Basically doing $a->getAB()->getDetails(); Which means that we need to implement 2).

But that sounds counterintuitive since that will mean, one must first create a new B entity and then create an A entity and point it to the B entity.

Which looks like B owns A - and is not what I want.

And in the reverse - if B has a foreign key to A, can I still tell A about B's existence, so I can do $a->getAB()->getDetails(); ?

2. B has another id, and A has a foreign key to it:

So it will be like: A={id,name,bId} B={bId,details} bId is unique, id is unique

But in this way - it seems like I am wasting a column for A. B won't know it's attached to A too which perhaps is a bad practice.

EDIT: But this doesn't solve any problem, just noticed I must again first create B, since any x from A needs to point to a valid y from B.

3. Is the problem about the automatic generation of my mappings?

Currently I am generating my XML mappings and entity classes from my MySQL database.

Could it be that this generation won't automatically tell A if B has a foreign key to it?

M. Ivanov
  • 283
  • 1
  • 2
  • 13

1 Answers1

1

One-To-One, Bidirectional association is what you're looking for (something like your example in point 2).
And yes - owning is important. Please also read about the concepts of owning and inverse sides of associations.
I'd say in your example A is the owning side - it has a name. Name is usually something more significant than details.

There's no problem to create both Entities at the same time;

$a = new A();
$a->setName("Alpha");

$b = new B();
$b->setDetails("Alpha goes first");

$a->setB($b);
$em->persist($a)->flush();

and both entities will be aware of the counterpart:

$a->getB();
$b->getA();

Again - there MUST be an owning side and you must maintain the logic.

Taz
  • 3,718
  • 2
  • 37
  • 59
  • Thanks, I've read all about it, and now it works. But sadly I've experienced another problem - the reverse side autoloads all the time, which is bad... Do I have any remedy? Or should I just not tell the reverse side about the relation at all? – M. Ivanov Aug 19 '15 at 20:36
  • I think it is related to [this Doctrine FAQ entry](http://doctrine-orm.readthedocs.org/en/latest/reference/faq.html#why-is-an-extra-sql-query-executed-every-time-i-fetch-an-entity-with-a-one-to-one-relation), and [this SO question](http://stackoverflow.com/q/9848747/709626) – Taz Aug 19 '15 at 21:34