diff --git a/src/Repository/IdentityMap.php b/src/Repository/IdentityMap.php index e543470d..cde70ac5 100644 --- a/src/Repository/IdentityMap.php +++ b/src/Repository/IdentityMap.php @@ -29,7 +29,7 @@ class IdentityMap private $repository; /** - * @var E[] + * @var IEntity[] * @phpstan-var array */ private $entities = []; @@ -123,6 +123,7 @@ public function create(array $data): ?IEntity } $entity = $this->entities[$id]; if (isset($this->entitiesForRefresh[$id])) { + $this->repository->attach($entity); // entity can be detached because of delete try $entity->onRefresh($data); unset($this->entitiesForRefresh[$id]); } diff --git a/tests/cases/integration/Relationships/relationships.oneHasMany.persistence.phpt b/tests/cases/integration/Relationships/relationships.oneHasMany.persistence.phpt index f56c3edd..db19e0da 100644 --- a/tests/cases/integration/Relationships/relationships.oneHasMany.persistence.phpt +++ b/tests/cases/integration/Relationships/relationships.oneHasMany.persistence.phpt @@ -8,11 +8,18 @@ namespace NextrasTests\Orm\Integration\Relationships; +use Nextras\Dbal\Drivers\Exception\ForeignKeyConstraintViolationException; +use Nextras\Dbal\Drivers\Exception\NotNullConstraintViolationException; +use Nextras\Orm\Mapper\Dbal\DbalMapper; use NextrasTests\Orm\Author; use NextrasTests\Orm\Book; use NextrasTests\Orm\DataTestCase; +use NextrasTests\Orm\Helper; use NextrasTests\Orm\Publisher; +use NextrasTests\Orm\User; +use NextrasTests\Orm\UserStat; use Tester\Assert; +use Tester\Environment; require_once __DIR__ . '/../../../bootstrap.php'; @@ -91,6 +98,35 @@ class RelationshipsOneHasManyPersistenceTest extends DataTestCase $this->orm->flush(); Assert::same([$book], iterator_to_array($author->books)); } + + + public function testForeignKeyInNonConnectedRelationship() + { + if ($this->section === Helper::SECTION_ARRAY) { + Environment::skip('Only for DB with foreign key restriction'); + } + + $user = new User(); + $user2 = new User(); + $user->friendsWithMe->add($user2); + $userStat = new UserStat(); + $userStat->user = $user; + $userStat->date = 'now'; + $userStat->value = 3; + $this->orm->persistAndFlush($userStat); + + try { + $this->orm->removeAndFlush($user); + } catch (ForeignKeyConstraintViolationException $e) { + /** @var DbalMapper $mapper */ + $mapper = $this->orm->userStats->getMapper(); + $mapper->rollback(); + $this->orm->refreshAll(); + } + + $friends = iterator_to_array($user->friendsWithMe); + Assert::same(1, count($friends)); + } } diff --git a/tests/db/mssql-init.sql b/tests/db/mssql-init.sql index b74483bd..99ff8d65 100644 --- a/tests/db/mssql-init.sql +++ b/tests/db/mssql-init.sql @@ -137,7 +137,7 @@ CREATE TABLE user_stats date datetimeoffset NOT NULL, value int NOT NULL, PRIMARY KEY (user_id, date), - CONSTRAINT user_stats_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT user_stats_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE NO ACTION ON UPDATE CASCADE ); diff --git a/tests/db/mysql-init.sql b/tests/db/mysql-init.sql index 1d900f72..f03c31ae 100644 --- a/tests/db/mysql-init.sql +++ b/tests/db/mysql-init.sql @@ -137,7 +137,7 @@ CREATE TABLE user_stats date TIMESTAMP NOT NULL, value int NOT NULL, PRIMARY KEY (user_id, date), - CONSTRAINT user_stats_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT user_stats_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE RESTRICT ON UPDATE CASCADE ); diff --git a/tests/db/pgsql-init.sql b/tests/db/pgsql-init.sql index 65823a7f..5d529e23 100644 --- a/tests/db/pgsql-init.sql +++ b/tests/db/pgsql-init.sql @@ -137,7 +137,7 @@ CREATE TABLE "user_stats" "date" TIMESTAMPTZ NOT NULL, "value" int NOT NULL, PRIMARY KEY ("user_id", "date"), - CONSTRAINT "user_stats_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT "user_stats_user_id" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE );