OneToOne Constraints #6298

Open
opened 2026-01-22 15:30:20 +01:00 by admin · 5 comments
Owner

Originally created by @parljohn on GitHub (Sep 17, 2019).

I have a database that I can't change or control because it is used in a windows application. I have to extend the database by creating extended onetoone tables but I don't pre-populate the tables with rows. This causes all my OnetoOne relationships to break because of the non-existing records. I get the need for the constraints, but why not a way out? Why now allow for a record to be auto-generated like a cascade "auto-generate" or something if it doesn't exist yet instead of just throwing exceptions?

Secondarily, when I add a new object to act in the place of the onetoone, it tries to update a non-updatable auto generated ID on the table i'm joining it to and that throws an exception as well.

It's pretty frustrating trying to find a way around this and still use the convenience of the relationship. Any input would help, thanks!

Originally created by @parljohn on GitHub (Sep 17, 2019). I have a database that I can't change or control because it is used in a windows application. I have to extend the database by creating extended onetoone tables but I don't pre-populate the tables with rows. This causes all my OnetoOne relationships to break because of the non-existing records. I get the need for the constraints, but why not a way out? Why now allow for a record to be auto-generated like a cascade "auto-generate" or something if it doesn't exist yet instead of just throwing exceptions? Secondarily, when I add a new object to act in the place of the onetoone, it tries to update a non-updatable auto generated ID on the table i'm joining it to and that throws an exception as well. It's pretty frustrating trying to find a way around this and still use the convenience of the relationship. Any input would help, thanks!
admin added the Question label 2026-01-22 15:30:20 +01:00
Author
Owner

@Ocramius commented on GitHub (Sep 17, 2019):

I don't understand the question: can you make an example of schema and ORN operation that fails?

@Ocramius commented on GitHub (Sep 17, 2019): I don't understand the question: can you make an example of schema and ORN operation that fails?
Author
Owner

@parljohn commented on GitHub (Sep 19, 2019):

Yes sorry, thanks for the follow up.
I have the following relationship configured:
/** @ORM\OneToOne(targetEntity="SedonaData\Entity\Customer\Boc")
** @ORM\JoinColumn(name="Customer_Id", referencedColumnName="Customer_Id")
**/

  • Where Customer_Id is the primary index in both tables (auto incremented in Customer, none in Boc).
  • I only need this to be one direction.
  • When asking for a Boc it thinks it has a Boc with the same customer id but fails however when any field is asked for in the boc with an EntityNotFoundException because no Boc actually exists.
  • The boc table is what I created to extend the Customer table because we cannot change the Customer table. As we're adding extended tables, records don't exist yet.
  • I added something on the getter to create a new Boc if the NotFound exception is experienced to create a record by default
    public function getBoc(){ try { $this->boc->getPaidByRep(); } catch ( EntityNotFoundException $e ) { $boc = new Boc(); $boc->setCustomerId( $this->getId() ); $this->setBoc( $boc ); $boc->setCustomer( $this ); } return $this->boc; }
  • Once persisted and flushed, it then tries to run an "UPDATE" query against the primary key of the Customer table which our MSSQL server rejects and that throws a PDO error.

I'm not sure what the cleanest solution here is or why OneToOne can't be more forgiving or auto create where there's missing record on inverse side.

@parljohn commented on GitHub (Sep 19, 2019): Yes sorry, thanks for the follow up. I have the following relationship configured: /** @ORM\OneToOne(targetEntity="SedonaData\Entity\Customer\Boc") ** @ORM\JoinColumn(name="Customer_Id", referencedColumnName="Customer_Id") **/ - Where Customer_Id is the primary index in both tables (auto incremented in Customer, none in Boc). - I only need this to be one direction. - When asking for a Boc it thinks it has a Boc with the same customer id but fails however when any field is asked for in the boc with an EntityNotFoundException because no Boc actually exists. - The boc table is what I created to extend the Customer table because we cannot change the Customer table. As we're adding extended tables, records don't exist yet. - I added something on the getter to create a new Boc if the NotFound exception is experienced to create a record by default `public function getBoc(){ try { $this->boc->getPaidByRep(); } catch ( EntityNotFoundException $e ) { $boc = new Boc(); $boc->setCustomerId( $this->getId() ); $this->setBoc( $boc ); $boc->setCustomer( $this ); } return $this->boc; }` - Once persisted and flushed, it then tries to run an "UPDATE" query against the primary key of the Customer table which our MSSQL server rejects and that throws a PDO error. I'm not sure what the cleanest solution here is or why OneToOne can't be more forgiving or auto create where there's missing record on inverse side.
Author
Owner

@lcobucci commented on GitHub (Oct 1, 2019):

@parljohn it still a bit confusing to me but I think I got it.

I believe your modelling things in the wrong way. If you can't change the Customer table, you should IMHO model the class exactly the way you have in the table (without any association to the "extended table"). That link should come from the other side (Boc), which you have full control over.

You can even model the Boc to act as some sort of decorator of the Customer, so that your system only interacts with the Boc and that hides all the complexity of the "extended tables".

Does this make any sense to you?

@lcobucci commented on GitHub (Oct 1, 2019): @parljohn it still a bit confusing to me but I think I got it. I believe your modelling things in the wrong way. If you can't change the `Customer` table, you should IMHO model the class exactly the way you have in the table (without any association to the "extended table"). That link should come from the other side (`Boc`), which you have full control over. You can even model the `Boc` to act as some sort of decorator of the `Customer`, so that your system only interacts with the `Boc` and that hides all the complexity of the "extended tables". Does this make any sense to you?
Author
Owner

@parljohn commented on GitHub (Oct 7, 2019):

@lcobucci Thanks for the response and what you're saying would work lovely if I had control over what got created first. Unfortunately, the Windows Application the company uses creates the Customer so no BOC exists. On top of that the Customer is the primary object which has many other relationships I need to account for, both onetomany and other onetoone relationships. With the OnetoOne relationship as it is now, I can't "add" a onetoone record, it must be inserted at the same time as the customer. The constraints are strange, onetoone assumes the records all exist and won't insert after after the fact. Any other ideas that would help?

@parljohn commented on GitHub (Oct 7, 2019): @lcobucci Thanks for the response and what you're saying would work lovely if I had control over what got created first. Unfortunately, the Windows Application the company uses creates the Customer so no BOC exists. On top of that the Customer is the primary object which has many other relationships I need to account for, both onetomany and other onetoone relationships. With the OnetoOne relationship as it is now, I can't "add" a onetoone record, it must be inserted at the same time as the customer. The constraints are strange, onetoone assumes the records all exist and won't insert after after the fact. Any other ideas that would help?
Author
Owner

@parljohn commented on GitHub (Oct 7, 2019):

The solution I have for now is a OneToMany and ManyToOne but it forces me to always just pop the first record off of the collection because there should only ever be one so it is not ideal and frankly just bugs me :)

@parljohn commented on GitHub (Oct 7, 2019): The solution I have for now is a OneToMany and ManyToOne but it forces me to always just pop the first record off of the collection because there should only ever be one so it is not ideal and frankly just bugs me :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6298