In Doctrine2, I can write the following if I want to create single-column indexes for a set of columns in an entity:
/**
* Project
*
* #ORM\Entity(repositoryClass="Company\SomeBundle\Entity\ProjectRepository")
* #ORM\Table(indexes={
* #ORM\Index(name="name_idx", columns={"name"}),
* #ORM\Index(name="started_idx", columns={"started"}),
* })
*/
However, what if I wanted to create an index for each column in this entity? Is there a shorthand for this, so that I don't have to write it explicitly for each column like in the above example?
Just list properties that should be indexed.
<?php
/**
* #Entity
* #Table(name="ecommerce_products",indexes={#index(name="search_idx",columns={"name","email"})})
*/
class ECommerceProduct
{
}
Related
I have a mapped superclass AbstractQuestion with single-table-inheritance.
/**
* #ORM\Entity
* #ORM\MappedSuperclass
* #ORM\Table(name="Question")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="dtype", type="string")
* #ORM\DiscriminatorMap({
* "simple": "SimpleQuestion",
* "dropdown": "DropdownQuestion"
* })
*/
abstract class AbstractQuestion
SimpleQuestion and DropdownQuestion inherit from this superclass.
/**
* Class SimpleQuestion.
* #ORM\Entity()
*/
class SimpleQuestion extends AbstractQuestion
I want to modify an existing SimpleQuestion and make it a DropdownQuestion.
When saving a question, I deserialise and merge the question, which contains an ID and the 'dtype' and other properties.
$dquestion = $this->serial->fromJson($request->getContent(), AbstractQuestion::class);
$question = $this->em->merge($dquestion);
$this->em->flush();
So I submit something like:
{ id: 12, dtype: 'dropdown', 'text': 'What is my favourite animal?'}
After the deserialisation, $dquestion is a DropdownQuestion object as I desired, but after the merge $question is a SimpleQuestion object as it was in the database previously, so any unique properties of DropdownQuestion are lost and the question is saved as a SimpleQuestion. Is there any way to work around this?
You will first have to delete the existing record (SimpleQuestion) and then insert the new record (DropdownQuestion). Type casting is not supported in Doctrine 2.
Note.
You can probably change the discriminator column with a pure SQL query, but this is absolutely not recommended and will for sure give you problems...
Check also the answers here and here since they might be interesting for you.
I would like to make uniqueConstraint user and lesson.
/**
* #ORM\Table(name="ReviewSchool",uniqueConstraints={
* #ORM\UniqueConstraint(name="lessonid", columns={"lesson", "user"})})
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class ReviewSchool
{
* #ORM\ManyToOne(targetEntity="Lesson",inversedBy="reviewschool")
* #ORM\JoinColumn(name="review_lesson", referencedColumnName="id",onDelete="cascade")
*/
private $lesson;
/**
*
* #ORM\ManyToOne(targetEntity="User",inversedBy="reviewschool")
* #ORM\JoinColumn(name="review_user",referencedColumnName="id",onDelete="cascade")
*/
private $user;
However it shows
[Doctrine\DBAL\Schema\SchemaException]
There is no column with name 'lesson' on table 'ReviewSchool'.
Surely I have 'lesson' column, how can I solve this?
I have misunderstood something??
It allows to hint the SchemaTool to generate a database unique constraint on the specified table columns. It only has meaning in the SchemaTool schema generation context.
So you have to use column names. In your case:
#ORM\UniqueConstraint(columns={"review_lesson", "review_user"})}
i'm pretty new to Symfony and Doctrine and i'm facing a problem trying to set Class Table Inheritance. I have a parent Entity, called "TeamActionTarget", and 2 children called "Player" and "Competition".
The model of my parent entity is the following :
// src/Van/TeamsBundle/Entity/TeamActionTarget.php
namespace Van\TeamsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Van\TeamsBundle\Entity\TeamActionTarget
*
* #ORM\Entity
* #ORM\Table(name="van_teams_actions_targets")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type_id", type="integer")
* #ORM\DiscriminatorMap( {"1" = "Competition", "2" = "Player"} )
*/
abstract class TeamActionTarget
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Doctrine2 generated me a parent table, with 2 fields, "id" and "type_id", and 2 children tables, with their own unique fields.
What I want to do now is to retrieve all children BY TYPE, from an integer value posted from a form.
So in a controller, I coded this :
$em->getRepository('VanTeamsBundle:TeamActionTarget')->findByTypeId($targetType);
But Symfony2 returns me an error :
Entity "Van\TeamsBundle\Entity\TeamActionTarget" has no field "typeId"
Which is true. The entity model doesn't contain this field, only the parent class does. So I tried to add this field in the entity model, but I get a error when trying to update the entity, saying there is a conflict between this field and the discriminator.
My question is pretty easy, How can I retrieve my children BY TYPE, posted from a form ?
When using single table inheritance, you have to use the repository of the child class directly:
$em->getRepository('VanTeamsBundle:Player')->findAll();
If you would like to retrieve the different child entities dependent on a form, you have to use the entity alias (e.g. VanTeamsBundle:Player) as the form field value and pass it to the getRepository() method. Another way of doing this is by performing a custom mapping between the form field value and the entity alias using data transformers.
I having a following issue, I need to make a relationship with two tables, but with no regular id, i need to use strings column. Something like this:
/**
* #ORM\Entity
* #ORM\Table(name="sigtap_tb_procedimento")
*/
class Procedimento
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="ExcecaoCompatibilidade", mappedBy="procedimento_restricao")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="co_procedimento")
*/
private $restricoes;
}
And another Entity
/**
* #ORM\Entity
* #ORM\Table(name="sigtap_rl_excecao_compatibilidade")
*/
class ExcecaoCompatibilidade
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Procedimento", inversedBy="restricoes")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="co_procedimento")
*/
private $procedimento_restricao;
}
co_procedimento_restricao and co_procedimento_restricao are string type, The relation does not working. How can i solve this issue?
Your relation needs to reference a primary key in the other table.
May be I misunderstood your question but cant you reference the id collumn the relationship like this:
/**
* #ORM\OneToMany(targetEntity="ExcecaoCompatibilidade", mappedBy="procedimento_restricao")
*/
private $restricoes;
/**
* #ORM\ManyToOne(targetEntity="Procedimento", inversedBy="restricoes")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="id")
*/
private $procedimento_restricao;
Take a look here:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html
using one-to-many relations with doctrine
The side using #OneToMany is always the inverse side of a relation from doctrine's pov ( possibly not what you consider being the inverse side ) and never has a join-column definition.
Remove the #JoinColumn annotation from class Procedimento.
#OneToMany has to use mappedBy and #ManyToOne (the owning side) uses inversedBy.
The join-column (or join-table) definition has to be on the owning side together with #ManyToOne.
When using a join-column the name of this column (which will be added to the table of the owning side entity aka the side being "many") will be specified by name="column_name" and the referenced foreign key to store in there is the referencedColumnName="id"definition of the #JoinColum annotation.
I would like to create a slug with the combinations of relations of external tables. I would like to take 2 values from a table and another value from un'atra table. I tried to do this but I do not understand how to add two values and another table .. and it is required to have the fields (in my case empty)?
/**
* #ORM\OneToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="profile")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* */
private $utente;
/**
* #Gedmo\Slug(handlers={
* #Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", options={
* #Gedmo\SlugHandlerOption(name="relationField", value="utente"),
* #Gedmo\SlugHandlerOption(name="relationSlugField", value="nickname"),
* #Gedmo\SlugHandlerOption(name="separator", value="-")
* })
* }, separator="-", updatable=true, fields={"empty"})
* #ORM\Column(length=64, unique=true)
*/
private $slug;
I would also email as well as username field,and add another relationField