学说:我找不到原因"通过没有配置为级联持久的关系找到了一个新实体..."

时间:2017-02-14 14:36:31

标签: symfony doctrine-orm

更新:我发现了问题,but I don't understand why它存在但我不知道如何修复它。

实际上,我会检查当前处理Job是否是重试的:

        if ($job->isRetry()) {
            $this->entityManager->persist($job->getRetryOf());
            $this->ioWriter->noteLineNoBg(sprintf(
                '[%s] Job "%s" on Queue "%s": this is a retry of original process #%s.',
                $now->format('Y-m-d H:i:s'), $job->getId(), $job->getQueue(), $job->getRetryOf()->getId()
            ));
        }

所以,此时,重试Job已加载,当我更新当前Job时,已重试的已经补充,但未经实体经理管理!为什么不呢?这是否意味着每次我致电Job#isRetry()时,我都会再次坚持重试Job

更多:如果我再次坚持,我在数据库中有重复的条目!

在那些日子里在StackOverflow上阅读,我已经阅读了另一个与我有类似问题的开发者问题:他讲述了使用两个不同的实体管理器:如何验证是否使用了实体管理器我的实体是否与我的服务一样?

这是我的原始问题

我有一个代表要执行的命令的Job实体。

现在,如果命令失败,我会创建一个新的Job实体,重试先前失败的Job

问题是我收到错误:

  

通过这种关系找到了一个新的实体   ' SerendipityHQ \包\ CommandsQueuesBundle \实体\作业#retriedBy'那   未配置为级联实体的持久操作:3。到   解决此问题:显式调用EntityManager#persist()on   这个未知的实体或配置级联持久存在此关联   映射例如@ManyToOne(..,cascade = {" persist"})。

我知道,这是StackOverflow上一个非常常见的问题:我已经搜索了几天的解决方案,但没有人在one-to-one自引用实体中出现此错误。所以他们的解决方案不适合我。

/**
 * Basic properties and methods o a Job.
 *
 * @ORM\Entity(repositoryClass="SerendipityHQ\Bundle\CommandsQueuesBundle\Repository\JobRepository")
 * @ORM\Table(name="queues_scheduled_jobs")
 */
class Job
{
    ...

    /**
     * @var  Job $retryOf If this Job is a retry of another job, here there is the Job of which this is the retry
     *
     * @ORM\OneToOne(targetEntity="SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job", inversedBy="retriedBy")
     * @ORM\JoinColumn(name="retry_of", referencedColumnName="id")
     */
    private $retryOf;

    /**
     * @var  Job $retriedBy
     *
     * @ORM\OneToOne(targetEntity="SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job", mappedBy="retryOf")ì
     */
    private $retriedBy;

    ...
}

第一个问题:这个maping是否正确?它有任何错误吗?

我已经尝试了所有可能的事情:在使用时尝试保留两个实体,分离然后重新保留,刷新,提取EAGER,同时设置retryOfretriedBy setRetryOf()(这个是拥有的一面,对吗?)...也使用级联选项(但这会复制数据库中的实体而不是更新已存在的实体)任何东西!问题依然存在。

当我从数据库加载实体时,它似乎就出现了。

让我们看一下这个日志:

[INFO] [2017-02-14 15:30:42] Job "1" on Queue "default": Initializing the process.                                      
"Marking job 1 with status pending"
[INFO] Checking 1 running jobs...                                                                                       
"Start marking 1 as retried"
"Marking job 1 with status retried"
[✖] [2017-02-14 15:30:57] Job "1" on Queue "default": Process failed.                                                   
 ! [NOTE] [2017-02-14 15:30:57] Job "1" on Queue "default": Retry with Job "3" (Attempt #1/3).                          
[INFO] [2017-02-14 15:31:00] Job "3" on Queue "default": Initializing the process.                                      
 ! [NOTE] [2017-02-14 15:31:00] Job "3" on Queue "default": this is a retry of original process #1.                     
"Marking job 3 with status pending"
[INFO] Checking 1 running jobs...                                                                                       
"Start marking 3 as retried"
"Marking job 3 with status retried"
[✖] [2017-02-14 15:31:17] Job "3" on Queue "default": Process failed.                                                   
 ! [NOTE] [2017-02-14 15:31:17] Job "3" on Queue "default": Retry with Job "4" (Attempt #2/3).                          
[INFO] [2017-02-14 15:31:19] Job "4" on Queue "default": Initializing the process.                                      
 ! [NOTE] [2017-02-14 15:31:19] Job "4" on Queue "default": this is a retry of original process #3.                     
"Marking job 4 with status pending"

Exception: A new entity was found through the relationship 'SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job#retriedBy' that was not configured to cascade persist operations for entity: 3. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}).

见最后几行:

[INFO] [2017-02-14 15:31:19] Job "4" on Queue "default": Initializing the process.                                      
 ! [NOTE] [2017-02-14 15:31:19] Job "4" on Queue "default": this is a retry of original process #3.                     
"Marking job 4 with status pending"

在此阶段,我刚刚从数据库中检索了Job#4,并尝试将其状态从new更新为pending

此时,我收到了属性为retriedBy的非托管实体的实体#3的错误。但是这个实体正在更新Job#4!怎么可能找不到它?而且,如果我再次坚持,错误仍然存​​在。

我真的不知道在哪里寻找这个bug。有人能帮助我吗?

更多代码

当我尝试将new作业的状态更新为pending并且此更改Job同时包含retryOfretriedBy属性时,会出现问题集。

要更改Job的状态,请使用课程JobsMarker

错误在方法markJobAsPending()处触发:

// Utils\JobsMarker.php
public function markJobAsPending(Job $job, array $info, Daemon $daemon)
{
    $this->markJob($job, Job::STATUS_PENDING, $info, $daemon);
}

实体管理器是一样的,我在$em->flush()处理过程中多次调用Job来更新Job的状态(原因可能是这个?这真的很奇怪!)。

流程是这样的:

  1. I get the Job to process from the database;
  2. 将其标记为as abortedas pending;
  3. Job退出时,我会将其标记为相应的状态:如果失败and can be retriedI create a new Job

    // Util \ JobsMarker.php public function markJobAsRetried(Job $ job,array $ info) {     //创建一个新的重试作业     $ retryJob = $ job-> createRetryJob();

    // Set this retry Job as a retry of the original one
    $retryJob->setRetryOf($job);
    
    $this->entityManager->persist($retryJob);
    
    $this->markJobAsClosed($job, Job::STATUS_RETRIED, $info);
    
    return $retryJob;
    

    }

  4. 那么,会发生什么?

    1. 我创建了Job#1,但这失败了;
    2. 我创建了一个新的Job#3(because I already have for other reasons a Job #2);
    3. 我得到Job#3并且标记状态为pending(`Utils \ JobsMarker);
    4. 作业#3失败,我创建了作业#4。
    5. 我得到Job#4并将其标记为pending我收到有关未管理实体的例外情况。而且我真的不明白为什么!
    6. 希望这能帮助你帮助我!

0 个答案:

没有答案