6
votes

I'm being bugged by an issue that seems very very puzzling. FYI - I know and I have read most of the doctrine questions around here, so I know the basics of doctrine and specifying relationships.

Below is how my data model looks (posting relevant sections of code)

class Sample
{

    /**
     * @ORM\OneToMany(targetEntity="Analysis", mappedBy="sample", cascade={"persist"})
     * 
     protected $analyses

     public function addAnalysis(Analysis $analysis)
     {
        $analyses->setSample($this);
        $this->analyses[] = $analyses;
     }
}

And Analysis

class Analysis
{

    /**
     * @ORM\ManyToOne(targetEntity="Sample", inverseBy="analyses", cascade={"persist"})
     * @ORM\JoinColumn(name="sample_id", referencedColumnName="id")
     * 
     protected $sample

     public function setSample(Sample $sample)
     {
        $this->sample = $sample;
     }
}

So one Sample can have multiple Analysis. While creating a new Analysis however, it is not letting me create one. It is throwing a NOT NULL constraint exception.

Below is the code I tried.

$analysis = new Analysis
$analysis->setUUID("seeebbbfg");
$analysis->setStatus(Analysis::STATUS_DONE);
$sample = $sample->addAnalysis($analysis)
$em->persist($sample);
$em->flush();

I have gone through many links and the doctrine documentation

Doctrine One-To-Many Relationship Won't Save - Integrity Constraint Violation many-relationship-wont-save-integrity-constraint-violation Symfony 2 doctrine persist doesn't work after updating Relationship Mapping Doctrine entities relationship

After going through this Doctrine "A new entity was found through the relationship" error, I tried to persist $analysis before persisting sample, but it gave an 'a new entity was found' error and then this official doctrine documentation http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/association-mapping.html

Not sure what I'm missing. Can anyone shed any light on this?

UPDATE 1

[Doctrine\DBAL\Exception\NotNullConstraintViolationException]

An exception occurred while executing

INSERT INTO analysis (id, uuid, type, status, submission_at, sample_id) VALUES (?,?,?,?,?,?) with params [202066, "seeebbbfg", "temp", 2, "2016-5-22 12:16:39", null]
null value in column "sample_id" violates not-null constraint
2
Could you provide full NotNull exception message?Jakub Matczak
@dragoste: There you go.verisimilitude

2 Answers

7
votes

I think you should add analysisto the Analyses collection before set Sample.

I guess $this->analyses is an ArrayCollection so, use the ArrayCollection::add() method to add a new object.

Please, try this part of code and let me know the result

class Sample
{
    /**
     * @ORM\OneToMany(targetEntity="Analysis", mappedBy="sample", cascade={"persist"})
     */ 
     protected $analyses

    public function __construct()
    {
        $this->analyses = new ArrayCollection();
    }


     public function addAnalysis(Analysis $analysis)
     {
        $this->analyses->add($analysis); 
        $analysis->setSample($this);

        return $this;
     }
}
0
votes

Credreak... Thanks for this... Doctrine is not very clear how these are constructed.

I actually modified your code to create a instance of "related field" (analyese) as an Array Collection @ _construct and then you can populate that Array with the actual Entity by passing it to the addAnalysis() function.

So the order of operations is: (as I understand it)

  • Construct an instance of Sample w/ an "related field" (analyese) Array
  • Construct an instance of Analysis and populate the Array
  • Pass the Analysis Array to the Sample analyese Array
  • Then flush the sample which will save the Analysis data to the database.

This worked for me.

class Sample
{
    /**
     * @ORM\OneToMany(targetEntity="Analysis", mappedBy="sample", cascade={"persist"})
     */  
protected $analyses

    public function __construct()
    {
        $this->analyses = new ArrayCollection();
    }


     public function addAnalysis(Analysis $analysis)
     {
        $this->analyses->add($analysis); 
        $analyses->setSample($this);

        return $this;
     }
}