Symfony2 Repositories and custom joins - mysql

Ok i have a couple of tables in a database that I CAN NOT change the the structure to. That being said what I am trying to accomplish is to have a controller interact with the entities, do a custom join and return the results.
MORE DETAILS:
1st table has id, username
2nd table has user_id, stat1, stat2, stat3
what i want is to search for all users in table 1 joining table 2. I can do this with straight MySQL pretty easy but i want to know how to do it the symfony way.

You need to tell Doctrine where to find each piece of information so that it can load all the properties every time you instantiate a new User object. In other words, you need to add custom Doctrine mapping information. Assuming you're adding your mapping information as inline annotations to your User's model class, the code would look something like this:
//in User.php
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="first_table_name")
*/
class User
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $username;
/**
* #ORM\OneToMany(targetEntity="UserStats")
*/
protected $stats;
//also define getters and setters for the above, of course
}
//in UserStats.php
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="table_two_name")
*/
class UserStats
{
/**
* I'm pretty sure doctrine will require that you add an Id column to table_two,
* which is what this is. If you can't add an Id, I'm not sure it'll work...
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/**
* The below assumes your stats are strings. If not, change the type attribute.
* #ORM\Column(type="string")
*/
protected $stat1;
/**
* #ORM\Column(type="string")
*/
protected $stat2;
/**
* #ORM\Column(type="string")
*/
protected $stat3;
//include appropriate getters/setters here too
}

Related

Symfony One to One relation SQL syntax error

I have two Doctrine Entites (AugustusGame and AugustusBoard) that contain a OneToOne relation : every Game has 1 Board and every Board has 1 Game.
AugustusGame :
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="AGORA\Game\AugustusBundle\Entity\AugustusPlayer", mappedBy="game")
*/
private $players;
/**
* #ORM\OneToOne(targetEntity="AGORA\Game\AugustusBundle\Entity\AugustusBoard", mappedBy="game",cascade={"persist"})
*/
private $board;
AugustusBoard :
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\OneToMany(targetEntity="AGORA\Game\AugustusBundle\Entity\AugustusCard", mappedBy="board", cascade={"persist"})
*/
private $deck;
/**
* #ORM\OneToMany(targetEntity="AGORA\Game\AugustusBundle\Entity\AugustusCard", mappedBy="board", cascade={"persist"})
*/
private $objLine;
/**
* #ORM\OneToOne(targetEntity="AGORA\Game\AugustusBundle\Entity\AugustusGame", mappedBy="board", cascade={"persist"})
*/
private $game;
And when I try to get a Game by its ID, it produces badly syntaxed SQL request :
$augGame = $this->manager->getRepository('AugustusBundle:AugustusGame')->find($gameId);
Like so :
'SELECT t0.id AS id_1, t10.id AS id_11, t10.tokenBag AS tokenBag_12
FROM augustus_game t0
LEFT JOIN augustus_board t10 ON WHERE t0.id = 16'
Obviously it's not the good way to write a LEFT JOIN, but since it's generated by Symfony I wonder how to fix this.
Do you have any idea of what could cause this ?
Thanks in advance.
Take a look at the Doctrine Docs on how to deal with the owning side and inverse side of a bidirectional onetoone relationship.
Your problem here is that you declared both entities as the owning side. Change the mappedBy attribute on one entity to inversedBy and you should be fine.

Symfony 3.4 Doctrine : The association refers to the inverse side field which is not defined as association

Entity\Recognition
/**
* #ORM\Entity
* #ORM\Table(name="c_rcgntn")
*/
class Recognition {
/**
* #ORM\Id
* #ORM\Column(type="integer", name="id")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\RecognitionType", inversedBy="id")
* #ORM\JoinColumn(name="fk_recogtype_id", referencedColumnName="id")
*/
protected $recogType;
Entity\RecognitionType
/**
* #ORM\Entity
* #ORM\Table(name="c_rcgntn_type")
*/
class RecognitionType {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Recognition",mappedBy="recogType")
*/
protected $id;
When running this in my dev environment, I see the errors show up in my profiler. It isn't a big issue as the code still runs and returns the joins properly. I just can't shake the error.
The association Entity\Recognition#recogType refers to the
inverse side field Entity\RecognitionType#id which is not
defined as association. The association
Entity\Recognition#recogType refers to the inverse side
field Entity\RecognitionType#id which does not exist.
You are mixing the definition of the "id" field in RecognitionType with the relation to Recognition entity. From RecognitionType remove line:
#ORM\OneToMany(targetEntity="AppBundle\Entity\Recognition",mappedBy="recogType")
That should be enough for a unidirectional relation, your definition of recogType field is enough for it.
If you want to add the relation in RecognitionType also, then add a new field to it:
/**
* ORM\OneToMany(targetEntity="AppBundle\Entity\Recognition", mappedBy="recogType")
*/
protected $recognition;
Note that no schema update is required after the above definition.

2 table relation in one record doctrine2

How to create a record of the two tables in the third to get a table in the third identifier of one of the two tables. Use ORM Doctrine2
Database image.
Something that now is:
// Account.php
/**
* #ORM\ManyToOne(targetEntity="UserCoworking", inversedBy="accountCoworking")
* #ORM\JoinColumn(name="acoount_id", referencedColumnName="id")
*/
private $userCoworking;
/**
* #ORM\ManyToOne(targetEntity="UserClient", inversedBy="accountUserClient")
* #ORM\JoinColumn(name="acoount_id", referencedColumnName="id")
*/
private $userClient;
// User coworking
/**
* #ORM\OneToMany(targetEntity="Account", mappedBy="userCoworking")
*/
private $accountCoworking;
// User client
/**
* #ORM\OneToMany(targetEntity="Account", mappedBy="userClient")
*/
private $accountUserClient;

Symfony Doctrine - Joins without foreign keys

I'm trying to set up a schema to capture twitter users and their followers.
I have two tables. TwitterUser and Follower. Follower has 3 fields - id, twitterUser, follower.
When a twitter user is a added to the table, I also add a row to Followers to join them with other users I may be interested in.
However, If I get Symfony/Doctrine to build the tables using something like the following-
/**
* #ORM\Entity
* #ORM\Table(name="follower")
* #ORM\HasLifecycleCallbacks
*/
class Follower
{
public function __construct()
{
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="TwitterUser", inversedBy="followers")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $twitterUser;
/**
* #ORM\ManyToOne(targetEntity="TwitterUser", inversedBy="following")
* #ORM\JoinColumn(name="follower_id", referencedColumnName="id")
*/
protected $follower;
...
It insists on creating a Foreign Key for follower that I don't want, as I don't want to have to get ALL twitter users to ensure that my joins always work.
The only way I can think to do it, is to remove the annotation and create the SQL for the join myself. Is there a smarter way to do it?
I suggest using a ManyToMany self-referencing relationship as describe below:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-to-many-self-referencing

Doctrine 2 with multiple indexes

I am developing using zend framework and doctrine2.1.
I have generated entities from database.
But the problem is: Doctrine doesn't recognize my indexes. They are not marked in entity annotations at all.
And when I go to validate-schema and dump sql from orm:schema-tool:update --dump-sql it generates sql to drop all my indexes across whole database.
I found that Doctrine has following annotation used for defining indexes:
indexes={#index(name="index_name",
columns={"database_column1","database_column2"}
)}
But this allows me to define one index for multiple columns and I don't really need that.
What I want is the ability to define multiple indexes on multiple columns, one index per column.
Is there a way I can achieve this? Is there a way that I can have annotation that defines multiple indexes.
I would say you can insert multiple indexes in the indexes property (but I haven't had the time to test it):
indexes={
#ORM\Index(name="index_name", columns={"database_column1","database_column2"}),
#ORM\Index(name="index_name2", columns={"database_column1"}),
#ORM\Index(name="index_name3", columns={"database_column2"})
}
Hope this helps you
Here is an example:
/**
* #Entity
* #Table(name="serial_number",indexes={
* #index(name="product_idx", columns={"product_id"}),
* })
*/
class SerialNumber { // Entity Class
/**
* #var int
*
* #Id
* #GeneratedValue
* #Column(type="integer")
*/
protected $id;
/**
* #Column(name="created_at", type="datetime")
* #var \DateTime
* */
protected $created;
/**
* #Column(name="updated_at", type="datetime")
* #var \DateTime
* */
protected $updated;
/**
* #Column(name="product_id", type="integer")
*/
protected $productID;
}