diff --git a/tests/Tests/Models/WrappedIntegerPrimaryKey/Category.php b/tests/Tests/Models/WrappedIntegerPrimaryKey/Category.php new file mode 100644 index 00000000000..11a68ad2aed --- /dev/null +++ b/tests/Tests/Models/WrappedIntegerPrimaryKey/Category.php @@ -0,0 +1,75 @@ + */ + #[OneToMany(targetEntity: self::class, mappedBy: 'parent')] + private Collection $children; + + public function __construct( + string $name, + self|null $parent = null, + ) { + $this->id = new IntegerId(random_int(0, (1 << 10) - 1)); + $this->name = $name; + $this->parent = $parent; + $this->children = new ArrayCollection(); + + $parent?->addChild($this); + } + + public function getId(): IntegerId + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getParent(): self|null + { + return $this->parent; + } + + /** @return ReadableCollection */ + public function getChildren(): ReadableCollection + { + return $this->children; + } + + /** @internal */ + public function addChild(self $category): void + { + if (! $this->children->contains($category)) { + $this->children->add($category); + } + } +} diff --git a/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerId.php b/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerId.php new file mode 100644 index 00000000000..58afbfab2b4 --- /dev/null +++ b/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerId.php @@ -0,0 +1,22 @@ +value; + } + + public function __toString(): string + { + return (string) $this->value; + } +} diff --git a/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerIdType.php b/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerIdType.php new file mode 100644 index 00000000000..3d0f08e2c18 --- /dev/null +++ b/tests/Tests/Models/WrappedIntegerPrimaryKey/IntegerIdType.php @@ -0,0 +1,63 @@ +getValue(); + } else { + throw new LogicException('Unexpected value: ' . $value); + } + } + + public function getSQLDeclaration( + array $column, + AbstractPlatform $platform, + ): string { + return $platform->getIntegerTypeDeclarationSQL(['unsigned' => true]); + } + + private function doGetBindingType(): ParameterType|int + { + return ParameterType::INTEGER; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/tests/Tests/ORM/Persisters/IntegerIdPersisterTest.php b/tests/Tests/ORM/Persisters/IntegerIdPersisterTest.php new file mode 100644 index 00000000000..57c350ecbc7 --- /dev/null +++ b/tests/Tests/ORM/Persisters/IntegerIdPersisterTest.php @@ -0,0 +1,107 @@ +createEntityManager(); + + $this->createDummyBlogData($entityManager, 1, 1); + + /** @var Category[] $topCategories */ + $topCategories = $entityManager->createQueryBuilder() + ->select('category') + ->from(Category::class, 'category') + ->andWhere('category.parent IS NULL') + ->getQuery() + ->setFetchMode(Category::class, 'children', ClassMetadata::FETCH_EAGER) + ->getResult(); + + self::assertCount(1, $topCategories); + + foreach ($topCategories as $topCategory) { + // the real count of children in db is 1 + self::assertCount( + 1, + $entityManager->createQueryBuilder() + ->select('category') + ->from(Category::class, 'category') + ->andWhere('category.parent = :parent') + ->setParameter('parent', $topCategory->getId()->getValue()) + ->getQuery() + ->getResult(), + ); + + // our collection is initialized + self::assertTrue($topCategory->getChildren()->isInitialized()); + + // but fails to load the children + self::assertSame(1, $topCategory->getChildren()->count()); + } + } + + private function createDummyBlogData( + EntityManager $entityManager, + int $categoryCount = 1, + int $categoryParentsCount = 0, + ): void { + for ($h = 0; $h < $categoryCount; $h++) { + $categoryParent = null; + + for ($i = 0; $i < $categoryParentsCount; $i++) { + $categoryParent = new Category('CategoryParent#' . $i, $categoryParent); + $entityManager->persist($categoryParent); + } + + $category = new Category('Category#' . $h, $categoryParent); + $entityManager->persist($category); + } + + $entityManager->flush(); + $entityManager->clear(); + } + + private function createEntityManager(): EntityManager + { + if ($this->entityManager !== null) { + return $this->entityManager; + } + + $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/../../Models/WrappedIntegerPrimaryKey'], isDevMode: true); + + if (! DbalType::hasType(IntegerIdType::NAME)) { + DbalType::addType(IntegerIdType::NAME, IntegerIdType::class); + } + + $connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'memory' => true], $config); + $entityManager = new EntityManagerMock($connection, $config); + + $schemaTool = new SchemaTool($entityManager); + $schemaTool->createSchema($entityManager->getMetadataFactory()->getAllMetadata()); + + $schemaValidator = new SchemaValidator($entityManager); + $schemaValidator->validateMapping(); + + $this->entityManager = $entityManager; + + return $entityManager; + } +}