[DDC-2414] Unable to create One-To-Many relation with composite keys Created: 25/Apr/13  Updated: 01/May/13  Resolved: 01/May/13

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers, Tools
Affects Version/s: Git Master, 2.3.3
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Bruno CHALOPIN Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: composite
Environment:

Ubuntu 12.04, PHP 5.4.9



 Description   

Given these entities :

/**
 * Class Domain
 *
 * @Entity
 * @Table(name="profils_domains")
 */
class Domain
{
    /**
     * @var string
     *
     * @Id
     * @Column(type="string", length=22, nullable=false)
     */
    protected $name = '';
}
/**
 * Class User
 *
 * @Entity
 * @Table(name="profils_users")
 */
class User
{
    /**
     * @var string
     *
     * @Id
     * @Column(type="string", length=22, nullable=false)
     */
    protected $name = '';

    /**
     * @var Domain
     *
     * @Id
     * @ManyToOne(targetEntity="Domain", fetch="LAZY")
     * @JoinColumn(name="domain", referencedColumnName="name", onDelete="CASCADE")
     */
    protected $domain;
    
    /**
     * @var Group[]|ArrayCollection
     *
     * @ManyToMany(targetEntity="Group", mappedBy="users")
     */
    protected $groups;
}
/**
 * Class Group
 *
 * @Entity
 * @Table(name="profils_groups")
 */
class Group
{
    /**
     * @var string
     *
     * @Id
     * @Column(type="string", length=22, nullable=false)
     */
    protected $name = '';

    /**
     * @var Domain
     *
     * @Id
     * @ManyToOne(targetEntity="Domain", fetch="LAZY")
     * @JoinColumn(name="domain", referencedColumnName="name", onDelete="CASCADE")
     */
    protected $domain;
    
    /**
     * @var User[]|ArrayCollection
     *
     * @ManyToMany(targetEntity="User", indexBy="name", fetch="EXTRA_LAZY")
     * @JoinTable(name="profils_groups_users",
     *      joinColumns={
     * @JoinColumn(name="group_name", referencedColumnName="name", onDelete="CASCADE"),
     * @JoinColumn(name="domain", referencedColumnName="domain", onDelete="CASCADE")
     *          },
     *      inverseJoinColumns={
     * @JoinColumn(name="user_name", referencedColumnName="name", onDelete="CASCADE"),
     * @JoinColumn(name="domain", referencedColumnName="domain", onDelete="CASCADE")
     *          }
     *      )
     */
    protected $users;
}

I want to link users and groups but only from the same domain.
I also want a user to be in one group only.
The only way with composite keys is to make One-To-Many, Unidirectional with Join Table but I can't put unique=true in the @JoinColumn of my inverseJoinColumns because it will generate a unique index for each field and not one composite. I also can't use @UniqueConstraint as it is not supported in @JoinTable.



 Comments   
Comment by Fabio B. Silva [ 28/Apr/13 ]

Hi Bruno,

Could you please explain it a little deeper ?
you describe an one-to-many relation but your mapping has a many-to-many Group#users.

Also, you shoud describe operations you are executing and which errors you got.

Cheers

Comment by Bruno CHALOPIN [ 29/Apr/13 ]

Hi fabio,

The relation i was trying to make is http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-unidirectional-with-join-table

However, it implies to use a unique contraint and as explain above when trying to create the schema via doctrine, as i use composite keys, it will generate 2 unique contraints (one for each field) and not one composite unique constraint.

Nevertheless, it seems like using composite keys is a lot buggy in doctrine (see http://www.doctrine-project.org/jira/browse/DDC-2413)

Comment by Benjamin Eberlei [ 01/May/13 ]

We discussed this in DDC-2413, this is not supported by Doctrine.

Generated at Sun Dec 21 17:25:23 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.