Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

doctrine2: undefined index - many-to-one with non default referencedColumnName does not persist entity

I'm using Symfony 2.1.2.

I have two entities and define a [many-to-one (bidirectional)] (1) association between them. I don't want to use the primary key for the foreign key (referencedColumnName). I want to use another integer unique column: customer_no

/**
 * @ORM\Entity
 * @ORM\Table(name="t_myuser")
 */
class MyUser extends BaseEntity // provides an id (pk)
{
    /**
     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="user")
     * @ORM\JoinColumn(name="customer_no", referencedColumnName="customer_no", nullable=false)
     */
    public $customer;
}

/**
 * @ORM\Entity
 * @ORM\Table(name="t_customer")
 */
class Customer extends BaseEntity // provides an id (pk)
{
    /**
     * @ORM\Column(type="integer", unique=true, nullable=false)
     */
    public $customer_no;

    /**
     * @ORM\OneToMany(targetEntity="MyUser", mappedBy="customer")
     */
    public $user;
}

When I try to persist a MyUser entity with an Customer entity, I get this error:

Notice: Undefined index: customer_no in ...\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php line 608

The schema on the db looks fine, these should be the important sql schema definitions:

CREATE UNIQUE INDEX UNIQ_B4905AC83CDDA96E ON t_customer (customer_no);
CREATE INDEX IDX_BB041B3B3CDDA96E ON t_myuser (customer_no);
ALTER TABLE t_myuser ADD CONSTRAINT FK_BB041B3B3CDDA96E FOREIGN KEY (customer_no) 
  REFERENCES t_customer (customer_no) NOT DEFERRABLE INITIALLY IMMEDIATE;

So there is definitely an index for customer_no

//update: I fix the inversedBy and mappedBy stuff, but this is not the problem.

(1) : http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

like image 650
timaschew Avatar asked Nov 04 '22 15:11

timaschew


1 Answers

@m2mdas:
Yes you're right, I thought it's possible because JPA (which has influence to doctrine) has this feature. The attribute referencedColumnName only for the case when your property does not match the table column.

Whatever, I found a solution by patching the BasicEntityPersister.php, see here the gist on github: https://gist.github.com/3800132

the solution is to add the property/field name and value for the mapping column. This information is already there but not bound to the right place. It have to be added to the $newValId arrray this way:

$fieldName = $targetClass->getFieldName($targetColumn);
$newValId[$fieldName] = $targetClass->getFieldValue($newVal, $fieldName);

It only works for ManyToOne reference. ManyToMany doesn't work.
For ManyToOne I test it with already existing entities. You can test it, too:

change the doctrine annotation in tests/Doctrine/Tests/Models/Legacy/LegacyArticle.php
from

@JoinColumn(name="iUserId", referencedColumnName="iUserId")

to

@JoinColumn(name="username", referencedColumnName="sUsername")
like image 97
timaschew Avatar answered Nov 15 '22 08:11

timaschew