Disable automatic Id field generation in Doctrine
this a part of my entity file:
<?php
namespace MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Variables
* #ORM\Table(name="variables")
* #ORM\Entity(repositoryClass="MyBundle\Repository\VariablesRepository")
*/
class Variables
{
/**
* #var int
* #ORM\Column(name="variablesRef", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $variablesRef;
/**
* #var string
* #ORM\Column(name="variablesLibelle", type="string", length=250)
*/
private $variablesLibelle;
when i try to create a schema :
erreur
Property MyBundle\Entity\Employeursecteur::$id does not exist
i want to Disable automatic Id field generation in Doctrine
i don't need the id Column
please help
If you want a primary key field without a generated value you just have to set the strategy of generation to none:
#ORM\GeneratedValue(strategy="NONE")
Related
in my entity Class i have added some new attributes and i want to update schema of my database. So when i run php app/console doctrine:schema:update --force im getting this error every time
[Doctrine\DBAL\Schema\SchemaException]
The table with name 'postgres.day' already exists.
and my database won't update. So does anyone know how to solve this problem?
I have read the other question with that problem but it didn't helped me. So can anyone explain me whats going on, or how to solve this? Thanks.
<?php
namespace DashboardBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RadniNalog
*
* #ORM\Table()
* #ORM\Entity
*/
class RadniNalog
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="time_from", type="string", length=255)
*/
private $time_from;
/**
* #var string
*
* #ORM\Column(name="time_to", type="string", length=255)
*/
private $time_to;
/**
* #var string
*
* #ORM\Column(name="full_date_time", type="string", length=255)
*/
private $full_date_time;
}
it can cause this error message if you want to use a table name which is already used by one of the installed bundles.
In your case the conflicting table name is: day.
#ORM\Table no name provided within your annotation, which is required. See: Doctrine ORM | 21. Annotations Reference
#ORM\Table(name="radniNalog")
Either don't add the annotation if you want the default behaviour of Doctrine or add it correctly with the required options.
Symfony 3.1 - Doctrine: I am trying to add relationships between entities and thereby want to add foreign key to link tables in my example. I tried several settings, utilizing various combination of arguments, but none of them were able to ALTER the tables with Foreign key.
My entities are namely "Trips" and "Airlines" with the content attached below. I would like to use airline_id as a foreign key inside trips table. Here are the extract from my entity scripts:
Entity#1: Trips
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="trips")
*/
class Trips
{
/**
* #ORM\Column(name="trip_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $trip_id;
/**
* #ORM\Column(name="airline_id", type="integer")
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Airlines")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="airline_id", referencedColumnName="airline_id")
* })
*/
private $airline_id;
}
Entity#2: Airlines
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="airlines")
*/
class Airlines
{
/**
* #ORM\Column(name="airline_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $airline_id;
/**
* #ORM\Column(type="string", length=80)
*/
private $name;
}
I tried updating the schema from console , but all it says is
Nothing to update - your database is already in sync with the current entity metadata.
Also tried deleting the table and re-creating them with console; the result did not change much and the foreign key is still missing. :/
Any thoughts, or perhaps you know the solution?
I have a few suggestions, as I've gone through the same process of design.
First off, should I presume that "a trip has one airline" and also "an airline has many trips"? This seems logical, and since you show #ORM\ManyToOne annotation for the Trips class, that would equate to my same presumptions.
If this is so, then these are the suggestions:
First, don't call the classes "Trips" and "Airlines", but rather in the singular, that is "Trip" and "Airline". This is object oriented thinking. So when you create a "Trip" Doctrine object, it represents a trip for example. This also makes you code more readable and also supportable from a future standpoint; as because when people read your code, they will understand that a single instance of a Trip (from the Trip class), represents a trip (that a person takes). This is important when designing code.
Given the above, make these code changes.
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="trip")
*/
class Trip
{
/**
* #ORM\Id
* #ORM\Column(name="trip_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $trip_id;
/**
* #ORM\ManyToOne(targetEntity="Airline", inversedBy="trips")
* #ORM\JoinColumn(name="trip_airline_id", referencedColumnName="airline_id")
*/
private $airline;
...
/**
* Set airline - Adds this trip to the passed in airline and sets the airline
* property to resultant airline.
*
* #param \AppBundle\Entity\Airline
*/
public function setAirline($airline){
$airline->addTrip($this);
$this->airline = $airline;
}
}
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="airlines")
*/
class Airlines
{
/**
* #ORM\Column(name="airline_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $airline_id;
/**
* #ORM\Column(type="string", length=80)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="Trip", mappedBy="airline")
*/
protected $trips = null;
...
public function __construct(){
// This is an array of trips.
$this->trips = new ArrayCollection();
}
...
/**
* Add trip - Adds a course to the array.
*/
public function addTrip($trip){
$this->trips[] = $trip;
}
}
Now you can get trips from the airline, and also you can do the other way around, get the airline from the trip.
When #ORM\Column is specified along with #ORM\JoinColumn on same column, then JoinColumn's association gets ignored and Foreign Key isn't created on table. so dont use both #ORM\Column and #ORM\JoinColumn in same column. There is no need to specify data type with #ORM\Column for associations, doctrine handles it and assign data type based on database engine. For MySql, it is int.
I have an Entity Employee
class Employee
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="WorkHour", mappedBy="employee", cascade={"persist", "remove"})
*/
private $workHours;
}
and WorkHour
class WorkHour
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Profile
*
* #ORM\ManyToOne(targetEntity="Employee", inversedBy="workHours")
* #ORM\JoinColumn(name="employee_id", referencedColumnName="id")
*/
protected $profile;
/**
* #var integer
*
* #ORM\Column(name="weekday", type="smallint")
*/
private $weekday;
/**
* #var \DateTime
*
* #ORM\Column(name="hour_from", type="time")
*/
private $hourFrom;
/**
* #var \DateTime
*
* #ORM\Column(name="hour_to", type="time")
*/
private $hourTo;
}
Now I'm confused when I'm going to add addWorkHour(), removeWorkHour() methods.
Usually one-to-many relation you can add as many relations as you want, but in my case, one employee can have only up-to-7 workHours, and for a specified weekday (from 0 to 6) can have only one (or no) record.
So I think what I need is something methods like,
public function setWorkHourByWeekday($hour_from, $hour_to, $weekday);
public function getWorkHourByWeekday($weekday);
And after set workhours for an employee, when you persist that employee,
I want doctrine delete those workhours that are no longer exist, update those workhours that are changed, and create new workhours that not exist before.
How can I implement this? Should I write these logic in class Employee or its Repository, or a WorkHourManager class?
I think WorkDay is a probably better name for your entity, so i'll use that :).
$workdays= $employee->getWorkDays();
$workdays->clear(); // Clear existing workdays
// Add new workdays
foreach(...) {
$workday = new WorkDay();
$workday ->setWeekday(0); // You could use a constant like `WorkDay::MONDAY`
$workday ->setStart('09:00');
$workday ->setEnd('17:00');
$workdays->add($workday);
}
Set orphanRemoval=true on $workHours to remove WorkHours without an Employee.
The setWeekday method in your Workday entity should throw an exception when an invalid weekday is supplied (other than 0-6). You could also use a Weekday value object in combination with Doctrine embeddables.
I'd go for a service or manager class in this case.
My advice is not to drop old workhours, maybe you don't needed now, but this data could be useful in the future. So, will be better just add workHours to the Employee and make a report the get the last workHours for today. About validations, there is a lot of ways of doing that. If you are working with forms and the rules are complex maybe you need read http://symfony.com/doc/current/cookbook/validation/custom_constraint.html , but maybe you can find alternatives in the action controller or the entity class itself.
I have a Message entity and a User one. I want to make users be able to send messages to others. I already can send and receive messages, everything is working fine, but in order to select the receiver of a message, a default drop-down with all the users is made.
What I want to do is change the drop-down to a text field and make an AJAX to the database and retrieve a list of users that are found matching the keyword inserted in the textfield. And when clicking upon one of them, the user is introduced in the textfield.
The problem that I am facing is that I don't know how to pass an entity instead of plaintext because I get this error
Argument 1 passed to PrivateMessageBundle\Entity\Message::setReceiver() must be an instance of CrudBundle\Entity\User, string given
Another question, is there a bundle or plugin that does this easier and I can modify? Or do I have to do it myself everytime for every ajax field?
I'm building the form like so
$builder
->add('title')
->add('content','textarea')
->add('receiver','text');
By default, receiver is a drop-down select and automatically selects the User entity, but once I change it to text it doesn't.
Here's also relevant parts of my entities, if you need them:
class Message
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=50)
*/
protected $title;
/**
* #ORM\ManyToOne(targetEntity="CrudBundle\Entity\User")
* #ORM\JoinColumn(referencedColumnName="id")
*/
protected $receiver;
/**
* #ORM\ManyToOne(targetEntity="CrudBundle\Entity\User")
* #ORM\JoinColumn(referencedColumnName="id")
*/
protected $sender;
/**
* #var string
*
* #ORM\Column(name="content", type="string", length=2000)
*/
protected $content;
And my User class, extending FOSUserBundle's BaseUser class.
class User extends BaseUser implements AuthorInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
I think there are two ways to solve this problem.
1) add a custum formfield with the mapped = FALSE attribute.
->add('ajaxsearch', null, array('mapped' => false))
2) use a data-transformer.
I want to do composite unique key in doctrine.
Those are my fields:
/**
* #var string $videoDimension
*
* #Column(name="video_dimension", type="string", nullable=false)
*/
private $videoDimension;
/**
* #var string $videoBitrate
*
* #Column(name="video_bitrate", type="string", nullable=false)
*/
private $videoBitrate;
How can I show doctrine, that those combined together are composite unique key?
Answer the question:
use Doctrine\ORM\Mapping\UniqueConstraint;
/**
* Common\Model\Entity\VideoSettings
*
* #Table(name="video_settings",
* uniqueConstraints={
* #UniqueConstraint(name="video_unique",
* columns={"video_dimension", "video_bitrate"})
* }
* )
* #Entity
*/
See #UniqueConstraint
In case someone want use PHP 8 Attributes instead of Doctrine annotations:
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\UniqueConstraint(
name: 'video_unique_idx',
columns: ['video_dimension', 'video_bitrate']
)]
I find it more verbose to use only ORM and then prefix ORM in annotations. Also note that you can break annotation to several lines to make it more readable especially if you have several items to mention (index in the example below).
use Doctrine\ORM\Mapping as ORM;
/**
* VideoSettings
*
* #ORM\Cache(usage="NONSTRICT_READ_WRITE")
* #ORM\Entity(repositoryClass="AppBundle\Repository\VideoSettingsRepository")
* #ORM\Table(name="emails", uniqueConstraints={
* #ORM\UniqueConstraint(name="dimension_bitrate", columns={"video_dimension", "video_bitrate"})
* }, indexes={
* #ORM\Index(name="name", columns={"name"})
* })
*/
class VideoSettings
I know this is an old question, but I came across it while looking for a way to create composite PK and thought it could use some update.
Things are actually much simpler if what you need is a Composite Primary Key. (Which, of course, guarantees uniqueness) Doctrine documentation contains some nice examples by this url: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html
So the original example could look something like this:
/**
* #var string $videoDimension
*
* #ORM\Id #ORM\Column(type="string")
*/
private $videoDimension;
/**
* #var string $videoBitrate
*
* #ORM\Id #ORM\Column(type="string")
*/
private $videoBitrate;
A few notes here:
Column "name" is omitted since Doctrine is able to guess it based on
the property name
Since videoDimension and videoBitrate are both parts of the PK - there is no need to specify nullable = false
If required - the Composite PK may be composed of foreign keys, so feel free to add some relational mappings
XML version :
<unique-constraints>
<unique-constraint columns="column1,column2" name="give_some_explicit_name" />
</unique-constraints>
More details in the docs :
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/xml-mapping.html#defining-indexes-or-unique-constraints