i have a table which has two columns that are foreign keys from another two tables. I would like to make them composite primary key together as well as foreign key each one.
Here is my Entity from symfony;
/**
* ilan_emlakOzellik
*
* #ORM\Table()
* #ORM\Entity
*/
class ilan_emlakOzellik
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="ilan")
* #ORM\JoinColumn(name="ilanId")
*/
private $ilanId;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="emlakOzellik")
* #ORM\JoinColumn(name="ozellikId")
* #ORM\Column(type="integer")
*/
private $ozellikId;
After the write this schema to db, i see primary keys but foreign keys are missing. How can i make them foreign key too? Thanks for helping.
Validate your schema - these mappings are incorrect. Either a field is a column, or it is an association. Having both mappings on the same field is not allowed:
/**
* ilan_emlakOzellik
*
* #ORM\Table()
* #ORM\Entity
*/
class ilan_emlakOzellik
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ilan")
* #ORM\JoinColumn(name="ilanId")
*/
private $ilanId;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="emlakOzellik")
* #ORM\JoinColumn(name="ozellikId")
*/
private $ozellikId;
Related
I have next entities:
/**
* Customer
*
* #ORM\Table(name="customer")
* #ORM\Entity()
*/
class Customer
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Account[]|ArrayCollection
*
* #ORM\OneToMany(targetEntity="Account", mappedBy="customer")
*/
private $accounts;
/**
* #var Account
*
* #ORM\OneToOne(targetEntity="Account")
*
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id",referencedColumnName="customer_id"),
* #ORM\JoinColumn(name="default_account_id", referencedColumnName="id")
* })
*/
private $defaultAccount;
}
/**
* Account
*
* #ORM\Table(name="account")
*/
class Account
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Customer
*
* #ORM\ManyToOne(targetEntity="Customer", inversedBy="accounts")
* #ORM\JoinColumn(nullable=false)
*/
private $customer;
}
Idea that customer has multiply accounts, onr of the account should be default for customer. I would like to use foreign key with multiply fields to ensure that default customer account belongs to this customer, but I'm getting next error:
Column name `customer_id` referenced for relation from MyBundle\Entity\Customer towards MyBundle\Entity\Account does not exist.
Actually there is no "customer_id" field on ORM level, because it is "customer.id" but I dont know how to reference it.
It seems that line #ORM\JoinColumn(name="id",referencedColumnName="customer_id"), is redundant. Try to configure this field as following:
/**
* #var Account
*
* #ORM\OneToOne(targetEntity="Account")
*
* #ORM\JoinColumn(name="default_account_id", referencedColumnName="id")
*/
private $defaultAccount;
By the way, I think it would be better if you just added a boolean column is_default into your Account entity.
The data model:
The entities:
Pet:
/**
* #ORM\Entity
* #ORM\Table(name="pet")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="pet_type", type="string")
*/
abstract class Pet
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\OneToMany(
* targetEntity="Collar",
* mappedBy="pet",
* cascade={"persist", "remove"},
* orphanRemoval=TRUE
* )
* #ORM\JoinColumn(name="collars", referencedColumnName="id")
*/
protected $collars;
/**
* #ORM\Column(type="integer")
*/
protected $age;
}
Cat:
/**
* #ORM\Entity
* #ORM\Table(name="cat")
*/
class Cat extends Pet
{
/**
* #ORM\Column(type="decimal")
*/
private $purringDecibels;
}
Collar:
/**
* #ORM\Entity
* #ORM\Table(name="collar")
*/
class Collar
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Pet", inversedBy="collars")
* #ORM\JoinColumn(name="pet", referencedColumnName="id", nullable=false)
*/
private $pet;
/**
* #ORM\Column(type="string", length="255")
*/
private $color;
}
The problem:
The generated tables are fine except pet: It lacks the collars column, therefore the bidirectionality is broken. While the pet ids do get stored on the collar table, I cannot fetch collars from a pet (i.e. $pet->getCollars()) as it always returns an empty collection.
What am I missing out here?
PS:
The validate console helper says all (mapping & db) is OK.
Yes, I have my getters and setters (i.e. adders and removers)
I know about the infamous performance impact of the combination between a CTI and this kind of relationship.
You do not need to have a "collars" column on the pet table. It is a one-to-many relationship, so the only table that need to "know" about pets are the collar table.
A bidirectional relationship does not mean you need two columns on two tables.
Your map seems correct.
I am using Zend 2 Framework and I am trying to get data using Doctrine 2.
However the following error is coming in the Entity file.
Doctrine\ORM\Mapping\MappingException
No identifier/primary key specified for Entity "Acl\Entity\Permission". Every Entity must have an identifier/primary key.
How can I specify the primary key?
I am using the following code.
/**
* User Permissions
*
* #ORM\Entity
* #ORM\Table(name="acl_permissions")
* #property int $id
* #property int $role_id
* #property int $resource_id
* #property string $action
*/
class Permission
{
/**
* #ORM\Column(type="integer")
*/
public $id;
/**
* #ORM\Column(type="integer")
* #ORM\OneToOne(targetEntity="Role")
* #ORM\JoinColumn(name="role_id", referencedColumnName="id")
*/
public $role;
/**
* #ORM\Column(type="integer")
* #ORM\OneToOne(targetEntity="Resource")
* #ORM\JoinColumn(name="resource_id", referencedColumnName="id")
*/
public $resource;
/**
* #ORM\Column(type="string")
*/
public $action;
public function getRole()
{
return $this->role;
}
public function getResource()
{
return $this->resource;
}
}
Have you checked the docs?
You can define a primary key by using the #ORM\Id annotation. In case the value is generated automatically (e.g. if using auto_increment), you also need to set the #ORM\GeneratedValue(strategy="IDENTITY") annotation.
I am trying to set up a relationship as shown below.
Each car can have one review.
A car has a primary key on 2 columns.
Review is referenced back to the car via the composite primary key.
Simple, in theory.
class Car {
/**
* #ORM\Id
* #ORM\Column(type="string")
*/
private $make;
/**
* #ORM\Id
* #ORM\Column(type="string")
*/
private $model;
/**
*
* #ORM\OneToOne(targetEntity="Review", mappedBy="car", cascade={"persist"})
*/
private $review;
}
class Review {
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="Car", inversedBy="review")
*/
private $car;
/**
* #var #ORM\Column(type="text")
*/
private $text;
}
When I try to generate the schema, the following error pops up.
Column name id referenced for relation from \Entity\Review towards
\Entity\Car does not exist.
What am I doing wrong?
After extensive research, I can say that the above structure is not supported by Doctrine, unfortunately.
I have two tables/entities client and site that have a many to many relationship combined by a join table client_site. Here are how my entities are setup.
Here is the client table entity
/**
* #Entity
* #Table(name="client")
*/
class Client
{
/**
* #Id #Column(type="bigint")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ManyToMany(targetEntity="Site", inversedBy="clients")
* #JoinTable(name="client_site",
* joinColumns={#JoinColumn(name="c_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="s_id", referencedColumnName="id")}
* )
*/
private $sites;
And the site table entity
/**
* #Entity
* #Table(name="site")
*/
class Site
{
/**
* #Id #Column(type="bigint")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ManyToMany(targetEntity="Client", mappedBy="sites")
*/
private $clients;
This is the client_site table entity
/**
* #Entity
* #Table(name="client_site",indexes={#index(name="FK_client_site",columns={"c_id"}),#index(name="FK_client_site_2",columns={"s_id"})})
*/
class ClientSite
{
/**
* #Id
* #ManyToOne(targetEntity="Client", inversedBy="ClientSite")
*/
private $client;
/**
* #Id
* #ManyToOne(targetEntity="Site", inversedBy="ClientSite")
*/
private $site;
This is the query I am trying to run
$query = Zend_Registry::get('em')
->createQuery('SELECT c, s
FROM Application\Models\Client c
JOIN c.sites s
WHERE c.is_active = 1');
$clients = $query->getResult();
And this is my error
No identifier/primary key specified for Entity 'Application\Models\ClientSite'. Every Entity must have an identifier/primary key.
I put the #Id on both fields in the ClientSite entity, as they are the composite primary keys for my joiner table. Can this not be done in Doctrine2? If it can't, what are my alternative options.
If you CAN do this, what have I done incorrectly?
This isn't currently supported by Doctrine 2.
However, they are working on adding support for this in an experimental branch. Apparently this might be included in the 2.1 release if it works without issues.