Skip to content

Commit

Permalink
repository: reattach entity in refreshAll()
Browse files Browse the repository at this point in the history
Entity may be detached from deletion try which failed
and entities are being just refreshed.
  • Loading branch information
hrach committed Jan 30, 2021
1 parent 74f8872 commit 365a6e5
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/Repository/IdentityMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class IdentityMap
private $repository;

/**
* @var E[]
* @var IEntity[]
* @phpstan-var array<int|string, E|false>
*/
private $entities = [];
Expand Down Expand Up @@ -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]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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));
}
}


Expand Down
2 changes: 1 addition & 1 deletion tests/db/mssql-init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
);


Expand Down
2 changes: 1 addition & 1 deletion tests/db/mysql-init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
);


Expand Down
2 changes: 1 addition & 1 deletion tests/db/pgsql-init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
);


Expand Down

0 comments on commit 365a6e5

Please sign in to comment.