In Symfony2, I have these columns in a user entity:
*
* #ORM\OneToOne(targetEntity="User", inversedBy="lovername")
* #ORM\JoinColumn(name="lover", referencedColumnName="id", onDelete = "SET NULL")
*/
private $lover;
/**
* #ORM\OneToOne(targetEntity="User", mappedBy="lover", cascade={"persist"}, fetch="EXTRA_LAZY")
**/
private $lovername;
The project is a dating website, where a user can send messages only to one user, which he/she chose. The column lover contains the id of user he/she chose to talk to.
It works properly, but it generates an additional SQL query. First Symfony downloads the row about the logged user and then every information about user which 'love' him, even if that information is useless. I need it only when user sends messages.
It is some way to write it/build database better? How do I control auto-generating queries in Symfony2?
I've also faced a similar problem. It seems like LazyLoad doesn't work properly for OneToOne relationships in doctrine. See this question
Related
I have two entities, a Flight and a Booking.
They are configured in a bi-directional one-to-one relationship, with the Flight underlying table holding the foreign key to the Booking underlying table.
The idea is that a Flight instance must be linked to a Booking, but a Booking can exist without a Flight.
/**
* #ORM\Entity
*/
class Flight{
/**
* #ORM\OneToOne(targetEntity="Booking", inversedBy="flight")
* #ORM\JoinColumn(name="bookingID", referencedColumnName="ID", nullable=false)
*/
private Booking $booking;
/// Rest of code removed for readability
}
/**
* #ORM\Entity
*/
class Booking{
/**
* #ORM\OneToOne(targetEntity="Flight", mappedBy="booking")
*/
private ?Flight $flight;
/// Rest of code removed for readability
}
I do not want to use cascading operations since a Flight can be removed without the Booking being removed (this is an extension of the idea stated above).
An issue arises when I try to delete both the Flight and the Booking.
Picture the following code:
// $flight holds a reference to $booking, as per the code above
$em->remove($flight);
$em->remove($booking);
$em->flush();
It would result in the following queries (logged by Doctrine)
START TRANSACTION
DELETE FROM flights WHERE ID = ?
INSERT INTO flights (redacted) VALUES (redacted)
DELETE FROM bookings WHERE ID = ?
ROLLBACK
Which I simply cannot understand.
If I remove the Booking directly through the underlying PDO Handle, it works perfectly, which means that is has to be a mapping issue, but I cannot see where I did something wrong. It's been driving me crazy for hours.
I have two entities with One-To-Many relationship - User and Log.
class User {
/** #OneToMany(targetEntity="Log", mappedBy="user") */
private $logs;
}
class Log {
/**
* #ManyToOne(targetEntity="User", inversedBy="logs")
* #JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
}
What I want to achieve is following - Once I delete the User entity, instead of cascade deleting all of that User logs, I want to be able to save those logs and still be able to keep that user_id. I was thinking of creating a new database table old_logs with the same structure as logs table, where all of the data from User entity will be copied to before deleting the User entity, as I believe I can't keep the user_id pointing to non-existing user (with the use of foreign keys).
Is something like this possible through doctrine Entity class?
I am looking for a clear explanation of how the relations work in Doctrine 2. I've been trying now for days to set up a OneToOne relation in Symfony3, and have read basically every thread and all the documentation, and i simply do not understand. The last few hours i've been bruteforcing my way into a OneToOne relation, with no luck.
Here's the problem i'm dealing with:
My user entity has a Team (which is itself an Entity)
/**
* #ORM\OneToOne(targetEntity="Gluckez\bballBundle\Entity\Team",
mappedBy="Owner")
* #ORM\Column(name="team_id")
*/
private $team;
And My Team has an Owner, which refers to the User:
/**
* #var User $Owner
* #ORM\OneToOne(targetEntity="Application\Sonata\UserBundle\Entity\User",
inversedBy="team_id")
* #ORM\JoinColumn(name="Owner_id", referencedColumnName="id")
*/
protected $Owner;
Now in my User table, i can see the relations, which do point to the right team. but doctrine complains about the inverse side User#team, that does not exist (even though i'm pretty sure i've defined it?)
I've tried countless times to change the inversedby, mappedby, name, referencedcolumnName, as well as dropping and recreating the database and tables. updating the doctrine schema's. i'm out of idea's.
Not a single answer out there, nor the documentation of doctrine points me in the right direction. I realize that there's a lot of threads out there on this, but none of them are clear, or even answered.
Try it like this:
Owner entity
/**
* #ORM\OneToOne(targetEntity="Gluckez\bballBundle\Entity\Team", mappedBy="owner")
*/
private $team;
Team entity
/**
* #ORM\OneToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="team")
*/
protected $owner;
As reference: Association Mapping
I have 2 linked entities: User and Acess. I want my doctrine User entity to have a field that informs me if the user has acesses or not.
I can't do a simple OneToMany relationship between the two tables, because there is thousands of acesses and it would be too costly to get thousands of records from the database once I only need to know if there is any.
What I would want is a field linked to a native query like:
select * from accesses where user = <whatever> limit 1
More specifically, something like:
/**
* USer
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User {
/**
* #ORM\Column(name="user_id", type="bigint", nullable=false)
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=300, nullable=false)
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\Query="select exists (select id_acesses from accesses where user = "$id" limit 1)"
*/
private $hasAcesses;
}
Is this possible ? is there another way to do this ?
Edit:
based on #Otanaught answer below, I have done some tests:
Using a OneToMany relation with EXTRA_LAZY fetch:
user-getAccesses()->isEmpty() selected the whole collection
user-getAccesses()->count() used count(*) in the database which took 243ms to return
for comparasion my query above who did what I want took 12ms in average with peeks of 2ms or even 1ms.
Maybe the good folks at doctrine could implement this at isEmpty for extra lazy queries ?
Thanx #Otanaught
Doctrine does not provide an annotation that allows you to specify a query for a property of an entity (Annotation reference). You could create a custom method in your repository to implement the check. Did you measure how costly the relation would be? With correct relations and indexes this should be a none issue, because doctrine lazy loads the relation? Check the doctrine documentation about extra lazy collections.
I am creating an application with guests, venues, events and guest-categories in symfony2 with doctrine. Being in touch for 3 weeks only with symfony2, I have accomplished to create the schema tables for all entities in sql, their between dependencies and crud for each one. My problem is more theoretical than practical.
I will create a bundle for security (from the Security bundle in the book or FOSUserBundle). Then I will set up three roles:
Administrator
Organiser
Guest
Each guest will have its own profile and each organiser will be "attached" to his guests - in simple words, the Organizer X will only communicate and view Guest X-1, X-2 etc. - he won't be able to view Y-1. It might seem very simple and funny to you that I am asking a question like that but... I am self taught :)
The question is: How can I attach an event to an organiser and its guests? The simplest method I can imagine is : set a unique token (or any self generated code) for every guest, event, category, event and join the tables.
If guest John with token=vsfv2435r3frwf24t5grf has any events/categories/venues
find the same token in the event or category or venue and assign permissions.
Does it sound logical or foolish ?
You need to look at doctrine association mapping (one to many, many to many, etc.. )
http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html
They are quite easy to set up (you can do it in Symfony with a annotations or in your yml schema file) and will let you do the kind of things you are describing easily, take a look at the Symfony documentation for databases for more info
http://symfony.com/doc/current/book/doctrine.html
You could just create cross table for Organiser and Guest indicating which event they do attend / organise. Each Guest would also have have cross table to Organiser. This way you could easily assign organisers to guests and filter by it (I'm assuming guests could attend multiple events etc).
In Doctrine world it'd look like this:
Event
...
/**
* #ORM\ManyToMany(targetEntity="Organiser", inversedBy="events")
*/
protected $organisers;
/**
* #ORM\ManyToMany(targetEntity="Guest", inversedBy="events")
*/
protected $guests;
Organiser
...
/**
* #ORM\ManyToMany(targetEntity="Event", mappedBy="organisers")
*/
protected $events;
/**
* #ORM\ManyToMany(targetEntity="Guest", mappedBy="organisers")
*/
protected $guests;
Guest
...
/**
* #ORM\ManyToMany(targetEntity="Event", mappedBy="guests")
*/
protected $events;
/**
* #ORM\ManyToMany(targetEntity="Organiser", inversedBy="guests")
*/
protected $organisers;