簡體   English   中英

Ramsey \\ UUID無法與Doctrine OneToOne關聯一起使用

[英]Ramsey\UUID not working with Doctrine OneToOne Associations

我正在為Symfony 3中的團隊構建項目管理工具。我正在使用ramsey / uuid-doctrine作為系統中的ID。

到目前為止,這對一對多或多對一關聯還不是問題,但是當我嘗試保持一對一關聯時,Doctrine並沒有將關聯實體轉換為其UUID,並且而是在SQL中保留一個null值。

在此示例中,我有一個WikiPage,它可以具有多個WikiPageVersions。 WikiPage與WikiPageVersion具有一對多關聯( versions屬性:用於頁面的所有版本),但與WikiPageVersion具有一對一( 單向 )關聯( currentVersion屬性:對於……)當前版本)。

WikiPage還具有與Project的多對一關聯(以跟蹤Wiki頁面用於哪個項目),並且正確填充了該屬性。

WikiPage實體

/**
 * @ORM\Table(name="wiki_page")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\Project\WikiPageRepository")
 */
class WikiPage
{
/**
 * @var Uuid
 * @ORM\Id
 * @ORM\Column(type="uuid")
 */
protected $id;
/**
 * @var Project
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Project\Project", inversedBy="wikiPages")
 * @ORM\JoinColumn(name="project_id", referencedColumnName="id")
 */
protected $project;
/**
 * @var string
 * @ORM\Column(name="title", type="text")
 * @Assert\NotBlank()
 */
protected $title;
/**
 * @var HiveWikiPageVersion
 * @ORM\OneToOne(targetEntity="AppBundle\Entity\Project\WikiPageVersion", fetch="EAGER")
 */
protected $currentVersion;
/**
 * @var ArrayCollection
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\Project\WikiPageVersion", mappedBy="wikiPage", cascade={"persist", "remove"})
 */
protected $versions;

// -- Class Methods
}

WikiPageVersion實體

/**
 * @ORM\Table(name="wiki_page_version")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\Project\WikiPageVersionRepository")
 */
class WikiPageVersion
{
    /**
     * @var Uuid
     * @ORM\Id
     * @ORM\Column(type="uuid")
     */
    protected $id;
    /**
     * @var WikiPage
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Project\WikiPage", inversedBy="versions")
     * @ORM\JoinColumn(name="wiki_page_id", referencedColumnName="id")
     * @Assert\NotBlank()
     */
    protected $wikiPage;
    /**
     * @var string
     * @ORM\Column(name="content", type="text")
     * @Assert\NotBlank()
     */
    protected $content;
    /**
     * @var string
     * @ORM\Column(name="version_comment", type="string", length=255)
     * @Assert\NotNull()
     */
    protected $versionComment;
    /**
     * @var HiveWikiPageVersion
     * @ORM\OneToOne(targetEntity="AppBundle\Entity\Project\WikiPageVersion")
     * @ORM\JoinColumn(name="previous_version", referencedColumnName="id")
     * @Assert\Type(type="Odev\Hive\Model\Entity\Project\WikiPageVersion")
     */
    protected $previousVersion;
    /**
     * @var \DateTimeInterface
     * @ORM\Column(name="created", type="datetime")
     * @Assert\NotBlank()
     */
    protected $created;
    /**
     * @var User
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
     * @ORM\JoinColumn(name="created_by", referencedColumnName="id")
     * @Assert\NotBlank()
     */
    protected $createdBy;
}
// -- Methods

到目前為止的故障排除

  1. 我可以確認,在持久保存WikiPage之前,已關聯WikiPageVersion。
  2. 我可以使用我的Project和WikiPageVersion實體復制相同的行為(對於Wiki主頁,Project與WikiPage具有一對一關聯,而WikiPageVersion與WikiPageVersion具有與自身的一對一關聯)。 一對一關聯不轉換UUID。
  3. 嘗試從Symfony Controller或從加載Doctrine固定裝置持久時,我遇到相同的問題。
  4. 我嘗試使用xdebug跟蹤轉換發生的位置,但我並不精通使用調試器,並且在調試器運行20分鍾后,我找不到該字段的轉換發生位置。 我要么跳過它發生的循環,要么就錯過它。 在花了一個小時跳過嘗試查找問題的運行之后,我不得不放棄。

這是我嘗試保留WikiPage時從教義中得到的錯誤:

[Doctrine\DBAL\Exception\NotNullConstraintViolationException]
An exception occurred while executing 'INSERT INTO wiki_page (id, project_home, title, project_id, current_version_id) VALUES (?, ?, ?, ?, ?)' with params ["ddc1f51a-f5d9-489f-89bb-cd79f3393af0", 1
, "Technical Reviews Wiki", "5138b185-b10b-48ac-a102-bdea1139c911", null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'current_version_id' cannot be null

和異常跟蹤(此異常來自在夾具加載期間保存的異常):

Exception trace:
() at /home/vagrant/hive/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:112
Doctrine\DBAL\Driver\AbstractMySQLDriver->convertException() at /home/vagrant/hive/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:128
Doctrine\DBAL\DBALException::driverExceptionDuringQuery() at /home/vagrant/hive/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php:177
Doctrine\DBAL\Statement->execute() at /home/vagrant/hive/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:281
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts() at /home/vagrant/hive/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1014
Doctrine\ORM\UnitOfWork->executeInserts() at /home/vagrant/hive/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:378
Doctrine\ORM\UnitOfWork->commit() at /home/vagrant/hive/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:356
Doctrine\ORM\EntityManager->flush() at /home/vagrant/hive/src/Odev/Hive/Infrastructure/AppBundle/DataFixtures/ORM/LoadProjectData.php:89
Odev\Hive\Infrastructure\AppBundle\DataFixtures\ORM\LoadProjectData->load() at /home/vagrant/hive/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/AbstractExecutor.php:121
Doctrine\Common\DataFixtures\Executor\AbstractExecutor->load() at /home/vagrant/hive/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php:88
Doctrine\Common\DataFixtures\Executor\ORMExecutor->Doctrine\Common\DataFixtures\Executor\{closure}() at n/a:n/a
call_user_func() at /home/vagrant/hive/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:233
Doctrine\ORM\EntityManager->transactional() at /dev/shm/app/cache/dev/appDevDebugProjectContainer.php:5645
DoctrineORMEntityManager_00000000015ce1f5000000002a2c79364ae5d79093a662a969d1540330e84087->transactional() at /home/vagrant/hive/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php:90
Doctrine\Common\DataFixtures\Executor\ORMExecutor->execute() at /home/vagrant/hive/vendor/doctrine/doctrine-fixtures-bundle/Command/LoadDataFixturesDoctrineCommand.php:118
Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand->execute() at /home/vagrant/hive/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:262
Symfony\Component\Console\Command\Command->run() at /home/vagrant/hive/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:848
Symfony\Component\Console\Application->doRunCommand() at /home/vagrant/hive/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:189
Symfony\Component\Console\Application->doRun() at /home/vagrant/hive/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:80
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /home/vagrant/hive/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:120
Symfony\Component\Console\Application->run() at /home/vagrant/hive/bin/console:29

在這一點上,我感到迷茫-如果對我應該去的地方有任何建議,或者其他人遇到了這個問題,我將很樂意提供指導。

更新

根據matteo的要求:

這是創建記錄並引發錯誤的夾具的load方法。

/**
 * {@inheritDoc}
 * @param ObjectManager $manager
 */
public function load(ObjectManager $manager)
{
    // Create ODEV Project Section
    $section = new ProjectSection(
        Uuid::uuid4(),
        'ODEV',
        'ODEV specific projects'
    );

    $manager->persist($section);
    $this->addReference('section-odev', $section);

    // Create Technical Review Project -> public
    $project = new Project(
        Uuid::uuid4(),
        'techreview',
        $section,
        'Technical Reviews',
        'Technical Reviews for Work Requests',
        false,
        false,
        $this->getReference('user-system'),
        $this->getReference('user-system'),
        '',
        $this->getReference('user-system')
    );

    // VarDumper::dump($project->getWikiHome()->getId());
    // VarDumper::dump($project->getCreatedBy()->getId());

    $manager->persist($project);
    $this->addReference('project-tech-review', $project);

    $manager->flush();
}

兩個VarDumper::dump()命令用於確認已創建關聯。

實際的WikiPage在Project的構造函數中生成,而WikiPageVersion在WikiPages的構造函數中生成。

這是Project的構造函數:

public function __construct(
    string $id,
    string $identifier,
    ProjectSection $section,
    string $name,
    string $description,
    bool $private,
    bool $sensitive,
    User $owner,
    User $contact,
    string $homepage,
    User $createdBy
) {
    $this->id = Uuid::fromString($id);
    $this->identifier = $identifier;
    $this->projectSection = $section;
    $this->name = $name;
    $this->description = $description;
    $this->private = $private;
    $this->sensitive = $sensitive;
    $this->owner = $owner;
    $this->contact = $contact;
    $this->homepage = $homepage;

    $this->createdBy = $createdBy;
    $this->created = new \DateTimeImmutable();
    $this->updatedBy = $createdBy;
    $this->updated = new \DateTimeImmutable();

    $this->archived = false;
    $this->workRequest = null;

    // set up collections
    $this->teamMembers = new ArrayCollection();
    $this->issues = new ArrayCollection();

    $this->folders = new ArrayCollection($this->defaultFolders());
    $this->wikiHome = $this->defaultWikiPage();
    $this->wikiPages = new ArrayCollection([$this->wikiHome]);
    $this->labels = new ArrayCollection($this->defaultLabels());
    $this->milestones = new ArrayCollection($this->defaultMilestones());
}

protected function defaultWikiPage(): WikiPage
{
    return new WikiPage(Uuid::uuid4(), $this, $this->name.' Wiki', '', $this->createdBy);
}

以及WikiPage的構造WikiPage

public function __construct(string $id, Project $project, string $title, string $content, User $createdBy)
{
    $this->id = Uuid::fromString($id);
    $this->project = $project;
    $this->title = $title;
    $this->content = $content;
    $this->created = new \DateTimeImmutable();
    $this->createdBy = $createdBy;

    $this->currentVersion = $this->createFirstVersion($content, $createdBy);
    $this->versions = new ArrayCollection([$this->currentVersion]);
}

protected function createFirstVersion(string $content, User $createdBy)
{
    return new WikiPageVersion(Uuid::uuid4(), $this, $content, $createdBy, 'Page Created');
}

希望能有所幫助。

當WikiPage實體嘗試插入時,它試圖插入其所有屬性。 檢查版本,如果=== null,則取消設置鍵索引。 那么當INSERT觸發時,parm數組只有4個鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM