I'm busy with a project in Symfony and I'm just checking the profiler tab and seeing 2 errors continuously popping up - they are below.
The mappings MyBundle\MainBundle\Entity\School#provinceId and MyBundle\MainBundle\Entity\Province#schools are incosistent with each other.
The association MyBundle\MainBundle\Entity\School#grades refers to the owning side field MyBundle\MainBundle\Entity\Grade#school_id which does not exist.
I'm getting a couple more of these and I can't understand why? What does it mean by "incosistent" (see what I did there)? Parts of my code is below if it's helpful.
In Province.php
/**
* #ORM\OneToMany(targetEntity="School", mappedBy="provinceId")
*/
private $schools;
and in my Schools.php
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Province", inversedBy="schools")
* #ORM\JoinColumn(name="province_id", referencedColumnName="id")
*/
private $provinceId;
And for the second error...
School.php
/**
* #ORM\OneToMany(targetEntity="Grade", mappedBy="school_id")
*/
private $grades;
and Grade.php
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="School", inversedBy="grades")
* #ORM\JoinColumn(name="school_id", referencedColumnName="id")
*/
private $schoolId;
I just want to know what these errors mean exactly and why these entities aren't right - I tried following the docs off the doctrine page but apparently I went wrong somewhere!
Thanks for any help!
I don't have your entire configuration, so I'm just going to make an educated guess here... (forgive me if I'm wrong!)
Regarding the first one, you say the mapping looks like this:
# Province.php
/**
* #ORM\OneToMany(targetEntity="School", mappedBy="provinceId")
*/
private $schools;
# School.php
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Province", inversedBy="schools")
* #ORM\JoinColumn(name="province_id", referencedColumnName="id")
*/
private $provinceId;
I imagine it's the types that are throwing things off here. You see, the purpose of the mappings is so that you can treat these things like objects, without having to worry about how they're persisted/connected in the database. Specifically, in your case, a School entity should not have a member $provinceId of type integer; rather, it should have a $province of type Province.
Try this:
# Province.php
/**
* #ORM\OneToMany(targetEntity="School", mappedBy="province")
*/
private $schools;
# School.php
/**
* #var Province
*
* #ORM\ManyToOne(targetEntity="Province", inversedBy="schools")
* #ORM\JoinColumn(name="province_id", referencedColumnName="id")
*/
private $province;
(Again, this is wholly untested, and I only have a part of what you have... but I think this will get you closer.)
Related
I'm working on a Symfony project (V3.4) and I'm using an existing DB (can't change it).
To interact with it I use doctrine annotations and the work is well done!
I manage to submit requests using JoinTable and JoinColumns but there is one last thing I don't know how to deal with ...
I have the following tables :
tables
I have the id from table A and I'm trying to get the libelle from the E table.
Is there a way to do it using annotations? For now I've already done it between 3 tables but I don't know how to do it for more :
#ORM\ManyToMany(targetEntity="")
* #ORM\JoinTable(name="",joinColumns={#ORM\JoinColumn(
name="",referencedColumnName="")}, inverseJoinColumns={#ORM\JoinColumn(
name="",referencedColumnName="", unique=true)})
If it's not possible I'm open to suggestions.
Thanks!
By looking at your need and your schema, i can tell you that you don't need many to many relationship. You should bidirectional relation across the entities(tables).
I don't know which kind of relation you have right now, but assuming one-to-one, you can setup relations following way:
EntityA
/**
* #OneToOne(targetEntity="EntityB", mappedBy="entityA")
*/
private $entityB;
EntityB
/**
* #OneToOne(targetEntity="EntityA", inversedBy="entityB")
* #JoinColumn(name="entityA_id", referencedColumnName="id")
*/
private $entityA;
/**
* #OneToOne(targetEntity="EntityC", mappedBy="entityB")
*/
private $entityC;
EntityC
/**
* #OneToOne(targetEntity="EntityB", inversedBy="entityC")
* #JoinColumn(name="entityB_id", referencedColumnName="id")
*/
private $entityB;
/**
* #OneToOne(targetEntity="EntityD", mappedBy="entityC")
*/
private $entityD;
EntityD
/**
* #OneToOne(targetEntity="EntityC", inversedBy="entityD")
* #JoinColumn(name="entityC_id", referencedColumnName="id")
*/
private $entityC;
/**
* #OneToOne(targetEntity="EntityE", mappedBy="entityE")
*/
private $entityE;
EntityE
/**
* #OneToOne(targetEntity="EntityD", inversedBy="entityE")
* #JoinColumn(name="entityD_id", referencedColumnName="id")
*/
private $entityD;
I didn't have time to test it. But it should be straight forward.
You can get libelle from E table following way:
$entityA = $entityRepositoryForA->find(a_id_here);
$entityA->getEntityB()->getEntityC()->getEntityD()->getEntityE->getLibelle();
I currently have to Entities in my application:
Page
Block
A Page can have many Blocks, which are shared across many Pages, so it is quite obvious that the relation is a ManyToMany. However, I need to be able to add the same Block twice (or more) to the same Page. Doctrine creates the "page_block" join table automatically, but with page_id and block_id both as Primary Keys, therefore adding a duplicate throws an error.
Is it possible, without adding an additional Entity, to tell doctrine to allow duplicates on the Page--Block relation ?
Well, I'm not sure about that behavior in doctrine, but if that is the case, then you can do something that I almost always do. Represent the ManyToMany relation as two OneToMany-ManyToOne. You must create your own PageBlock entity and configure it's foreign keys.
class Page{
/**
* #var array
*
* #ORM\OneToMany(targetEntity="PageBlock", mappedBy="page", cascade={"all"})
*/
private $pageBlocks;
}
class Block{
/**
* #var array
*
* #ORM\OneToMany(targetEntity="PageBlock", mappedBy="block", cascade={"all"})
*/
private $pageBlocks;
}
class PageBlock{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \stdClass
*
* #ORM\ManyToOne(targetEntity="Page", inversedBy="pageBlocks")
* #ORM\JoinColumn(name="id_page", referencedColumnName="id")
*/
private $page;
/**
* #var \stdClass
*
* #ORM\ManyToOne(targetEntity="Block", inversedBy="pageBlocks")
* #ORM\JoinColumn(name="id_block", referencedColumnName="id")
*/
private $block;
}
As you can see the primary key remains as ID, so problem resolved. I say almost always do because this is how I do it if I need an extra attribute in the relation(almost always it happens). I suspect that could be a way of do it with the ManyToMany annotation, but there is no difference with this approach.
Hope this help you.
At the beginning sorry for my poor English, I hope you understand me. I'm writing a simple portal in Symfony2 and came to the point where it needs to make relationships between tables with MySQL, all the ways of the internet browsed, tested and nothing came of it. The tables below.
http://i.stack.imgur.com/vR77x.png
http://i.stack.imgur.com/GDXDw.png
Now yes, by getting the user from the database, I would like to once stretched to the profession (vocation), but together with its name, is even an option?
If I understand correctly you want to create a OneToOne relationship between your Entities?!
On the Player entity:
/**
* Player
*
* #ORM\Table(name="players")
* #ORM\Entity()
*/
class Player
{
/**
* #ORM\OneToOne(targetEntity="Vocation", inversedBy="player")
* #ORM\JoinColumn(name="vocation", referencedColumnName="id")
*/
private $vocation;
...
}
And at the Vocation one
/**
* Vocation
*
* #ORM\Table(name="vocations")
* #ORM\Entity()
*/
class Vocation
{
/**
* #ORM\OneToOne(targetEntity="Player", mappedBy="vocation")
*/
private $player;
/**
* #var string
*/
private $vocationName;
/**
* #var integer
*/
private $id;
...
}
Something like this?
Also (from looking at your tables) maybe you possibly want a ManyToOne relationship instead of a OneToOne?
When searching I came up with many results of people having similar problems but they were always related to association errors. I'm trying add a simple text field to a table in a database and, for the life of me, I can't figure out what's different about this time - when I've done it with no problems many times before.
I've added a 'record_checksum' field to 4 different entities, but I will use just one, here to simplify the example. (The same error happens for all 4).
Here is an example of my Entity\Cloud.php file, with the 'record_checksum' field added at the bottom:
use Doctrine\ORM\Mapping as ORM;
namespace Entity;
/**
* Entity\Cloud
*
* #orm:Table(name="cloud")
* #orm:Entity
* #orm:HasLifecycleCallbacks
*/
class Cloud
{
/**
* #var integer $id
*
* #orm:Column(name="id", type="integer", length="13")
* #orm:Id
* #orm:GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var float $position_x
*
* #orm:Column(name="position_x", type="float", length=9)
*/
private $position_x;
/**
* #var float $position_y
*
* #orm:Column(name="position_y", type="float", length=9)
*/
private $position_y;
/**
* #var string $commit_group
*
* #orm:Column(name="commit_group", type="string", length=32, nullable=true)
*/
private $commit_group;
/**
* #var string $commit_key
*
* #orm:Column(name="commit_key", type="string", length=13, nullable=true)
*/
private $commit_key;
/**
* #var string $record_checksum
*
* #orm:Column(name="record_checksum", type="string", length=32, nullable=true)
*/
private $record_checksum;
The rest of the class is getter/setter methods, so I will leave it out. To see the entire Entity file, I put it up on pastebin ( http://pastebin.com/9LheZ6A1 ). The 'commit_key' I'd just added a few weeks ago, with no problems.
Now I update the schema:
$ doctrine orm:schema-tool:update --dump-sql
ALTER TABLE cloud ADD record_checksum VARCHAR(32) DEFAULT NULL;
$ doctrine orm:schema-tool:update --force
Updating database schema...
Database schema updated successfully!
I verified this field now exists in the DB table.
However, when I run a simple DQL query like this:
$dql = "SELECT c.id AS id, c.commit_key AS key, c.record_checksum AS checksum ".
"FROM Entity\\Cloud c WHERE c.commit_group = :commit_group";
I get the error:
[Semantical Error] line 0, col 42 near 'record_checksum': Error: Class Entity\Cloud has no field or association named record_checksum,
I've banged my head on the wall over this for a while now. I'm sure I'm overlooking something really stupid. Any help is greatly appreciated!
-Nick
Try to:
Clear any cache that may contain the config or PHP code.
Rename a field in case the first solution didn't work.
Go to the Entity in question and check the variable name. If it's something like TESTVar, and you're trying to use testVar in the query, it's going to give you the error that the variable doesn't exist in the Entity.
Change the query to use TESTVar instead of testVar, and it will work.
OK, if anyone can help me with this that would be great, because it appears to be intractable.
I have 2 entities set up in a new zf-boilerplate project as below. I am trying to follow the tutorial on Zendcasts.com - One-to-Many with Doctrine 2, but can't get doctrine to recognise the associations I have mapped. If I run orm:schema-tool:create --dump-sql, it dumps the generated Sql, but NOT the ALTER TABLE statements at the end which should would create the Foreign Key Mapping, I can't get that to work properly.
I've tried everything I can think of, the JOIN statement I need to run obviously doesn't work either, but I figure if I can just get Doctrine to recognise the ALTER statement I can carry it from there.
Any ideas would be great, let me know if you need more info. I thought at first maybe the .ini file might be set up wrong, but I think this is more something to do with the relationship annotation?
Library/Photo/Entity/Gallery.php
<?php
namespace Photo\Entity;
/**
* #Entity(repositoryClass="Photo\Entity\Repository\MyGallery")
* #Table(name="gallery")
*/
class Gallery {
/**
* #Id #GeneratedValue
* #Column(type="smallint",nullable=false)
* #var integer
* #OneToMany(targetEntity="Photo", mappedBy="galleryID")
*/
protected $id;
/**
* #Column(type="string", length=200)
* #var string
*/
protected $gallery;
Library/Photo/Entity/Photo.php
<?php
namespace Photo\Entity;
/**
* #Entity(repositoryClass="Photo\Entity\Repository\MyPhoto")
* #Table(name="photo")
*/
class Photo {
/**
* #Id #GeneratedValue
* #Column(type="smallint",nullable=false)
* #var integer
*/
protected $id;
/**
* #Column(type="smallint",nullable=false)
* #var integer
* #ManyToOne(targetEntity="Gallery")
* #JoinColumns({
* #JoinColumn(name="gallery_id", referencedColumnName="id")
* })
*/
protected $galleryID;
Hmm... I see.. Check you column names, gallery_id vs galleryID looks suspicious.
If it is gallery_id, then you have to change the $galleryID annotation to #Column(type="smallint", nullable=false, name="gallery_id")
Generally, everywhere in the object model you should use the object field names, for example mappedBy="galleryID", but the column itself should be mapped with the appropriate DB name, like I mentioned #Column(name="gallery_id"), or for example #JoinColumns({#JoinColumn(name="gallery_id" referencedColumnName="id")})