-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removing one side of BiDi 1-1 relation throws #11580
Comments
Relevant field definitions:
This was added (along with
|
It seems that changing |
It would be great to get some feedback regarding this
|
I wouldn't be so sure. Looking at the stack trace, we can see that we are here: Lines 353 to 369 in cfc0655
So, directly inside I think you should debug further as to why this entity is considered new, but before that, have you validated your schema? I find it suspicious that such a big bug with what appears to be a pretty common situation happens at all. You could also try reproducing it with a test. |
@greg0ire Do you have a test already that deletes an entity on the owner side of a BiDi relation? I'd think no, which is why it was not noticed |
@greg0ire This reproduced the error reliably for me <?php
// bootstrap.php
use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Mapping as ORM;
require_once "vendor/autoload.php";
#[Entity]
class Customer {
#[ORM\Id]
#[ORM\Column( type: 'integer' )]
#[ORM\GeneratedValue]
private int|null $id = null;
/** One Customer has One Cart. */
#[OneToOne( targetEntity: Cart::class, mappedBy: 'customer' )]
public Cart|null $cart = null;
#[ORM\Column( type: 'string' )]
private string $name = 'qwe';
public function getName(): string {
return $this->name;
}
public function setName( string $name ): void {
$this->name = $name;
}
}
#[Entity]
class Cart {
#[ORM\Id]
#[ORM\Column( type: 'integer' )]
#[ORM\GeneratedValue]
public int|null $id = null;
/** One Cart has One Customer. */
#[OneToOne( targetEntity: Customer::class, inversedBy: 'cart' )]
#[JoinColumn( name: 'customer_id', referencedColumnName: 'id' )]
public Customer|null $customer = null;
}
unlink( 'db.sqlite' );
$database = new SQLite3( 'db.sqlite' );
$database->query( 'CREATE TABLE if not exists Cart (
id integer PRIMARY KEY,
customer_id INT DEFAULT NULL
);
CREATE TABLE if not exists Customer (
id integer PRIMARY KEY,
name varchar DEFAULT NULL
);' );
// Create a simple "default" Doctrine ORM configuration for Attributes
$config = ORMSetup::createAttributeMetadataConfiguration(
paths: [],
isDevMode: true,
);
// configuring the database connection
$connection = DriverManager::getConnection( [
'driver' => 'pdo_sqlite',
'path' => __DIR__ . '/db.sqlite',
], $config );
// obtaining the entity manager
$entityManager = new EntityManager( $connection, $config );
//$schemaTool = new \Doctrine\ORM\Tools\SchemaTool($entityManager);
//$classes = $entityManager->getMetadataFactory()->getAllMetadata();
//$schemaTool->createSchema($classes);
$cart = new Cart();
$cart->customer = new Customer();
$entityManager->persist( $cart->customer );
$entityManager->persist( $cart );
$entityManager->flush();
$entityManager->clear(); // simulate separate run
$cart = $entityManager->find( Cart::class, $cart->id );
$cart->customer->getName(); // initialize proxy
$entityManager->remove( $cart );
$entityManager->flush();
$cusomer = $entityManager->getRepository( Customer::class )->findAll()[ 0 ];
$cusomer->setName( 'asd' );
$entityManager->flush(); // throws here
echo 'OK', PHP_EOL; Output
|
Is it a minimal reproducer? For instance, is the |
How would I know if it is necessary? I took this code from your official docs at https://www.doctrine-project.org/projects/doctrine-orm/en/2.19/reference/association-mapping.html.
Sorry, does it mean the a PHP file that you can run from CLI or IDE directly is not acepted as reproduction case? I'd think that you could convert it to a PHPUnit test in less than 5 minutes if you were interested in this bug, without the lengthy procedure of me creating a PR just for it to chill in the waiting list with another 298 PRs you already have. |
Let me focus on the 298 PRs first (more actually if you can't other repos), and I will get back to you. |
Bug Report
Summary
I have added an
inverseBy
field to an existing entity class so as to use it in the BiDi 1-1 fashion. The DB structure did not change. The setup is similar to the example given at https://www.doctrine-project.org/projects/doctrine-orm/en/2.19/reference/association-mapping.html#one-to-one-bidirectional.After this, under certain scenarios, deleting an entity throws an Exception.
Specifically, the entities are loaded via a DQL query:
This returns a nested object structure as expected:
After removing the
$confirmation
entity the structure becomes instable:When I try commit the transaction after this, I get an exception:
Which means that Doctrine is trying to persist the
confirmation
entity back to the DB.This is the opposite to what the code did before successfully (before the additing of the
inversedBy confirmation
field in theEvent
entity.Current behavior
Throws
How to reproduce
Delete the owner side of a BiDi 1-1 relation and commit.
Expected behavior
Delete successful. The inversed side changes to null.
The text was updated successfully, but these errors were encountered: