Symfony one to many dql query - php

I am creating symfony web app and have problem with making appropiate dql query for inbox.
This is code of entity causing problems:
class Message
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #OneToOne(targetEntity="User")
* #JoinColumn(name="fromUser", referencedColumnName="id")
*/
protected $fromUser;
/**
* #ORM\Column(type="text")
*/
protected $fromEmail;
/**
* #return mixed
*/
/**
* #OneToOne(targetEntity="User")
* #JoinColumn(name="toUser", referencedColumnName="id")
*/
protected $toUser;
/**
* #ORM\Column(type="text",length=255)
*/
protected $subject;
/**
* #ORM\Column(type="datetimetz")
*/
protected $date;
/**
* #ORM\Column(type="text")
*/
protected $toEmail;
/**
* #ORM\Column(type="text")
*/
protected $content;
/**
* #ORM\Column(type="boolean")
*/
protected $sent;
/**
* #ORM\Column(type="boolean")
*/
protected $spammed;
/**
* #ManyToMany(targetEntity="View")
* #JoinTable(name="messages_views",
* joinColumns={#JoinColumn(name="message_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="view_id", referencedColumnName="id", unique=true)}
* )
*/
protected $view;
class View extends CollectionType
{
public function __construct($user)
{
$this->user = $user;
$this->trashed = false;
$this->deleted = false;
$this->seen = false;
}
/**
* #ORM\Column(type="boolean")
*/
protected $trashed;
/**
* #ORM\Column(type="boolean")
*/
protected $deleted;
/**
* #ORM\Column(type="boolean")
*/
protected $seen;
/**
* #ManyToOne(targetEntity="User")
* #JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
}
$view is class ArrayCollection() and one to many relationship.
And i want to choose field "where $toUser = :me" and which contains $view where $view->user = :me and $view->trashed = false" (in case if there are two $view's (not possible/expected ) choose first found)
Thanks in advance for your time.
Edit:
at the moment i have something like this
$get = $this->getEntityManager()
->createQuery('
SELECT m
FROM MonoAdminBundle:Message m
WHERE m.userTo = :me AND m.sent = true
AND
ORDER BY m.date DESC
')
->setParameter('me', $me->getId())->getArrayResult();
$ret = new \Doctrine\Common\Collections\ArrayCollection();
foreach ($get as $message) {
if ($message->getSpammed() === false) {
foreach ($message->getView() as $view) {
if ($view->getUser() == $me) {
if ($view->getTrashed() === false) {
$ret->add($message);
}
}
}
}
}
But it is not good idea as i want to use paginator.

Try to use a queryBuilder.
$qb = $entityManager->getRepository(Message::class)->createQueryBuilder('m');
$qb->addWhere('m.toUser = :me')
->innerJoin('m.view', v)
->addWhere('v.user = :me')
->addWhere('v.trashed = :isTrashed')
->setParameter('me', $user)
->setParameter('isTrashed', false);
To get DQL:
$qb->getQuery()->getDQL();
Then get results:
$qb->getQuery()->getResults();

Related

Many to One to Many doctrine, persist only one side

I have a system with two tables and a join table. Reuniao have many Servidor and a Servidor have many Reuniao. For this I have a reuniao table, servidor table and reuniaoservidor table. I want to persist a reuniao with many existing servidor, but I don't want to persist a servidor when a reuniao is persisted. The problem is...
When I try to persist a reuniao doctrine says to me:
"A new entity was found through the relationship 'SistemaIfnmg\Entity\Reuniao#servidores' that was not configured to cascade persist operations for entity: SistemaIfnmg\Entity\ReuniaoServidor#000000006a69473200007f33ddb737e2. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'SistemaIfnmg\Entity\ReuniaoServidor#__toString()' to get a clue."
The Entyties:
Reuniao.php
namespace SistemaIfnmg\Entity;
use SistemaIfnmg\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="reuniao")
* #ORM\HasLifecycleCallbacks()
*/
class Reuniao
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $titulo;
/**
* #ORM\Column(type="string", length=255)
*/
private $descricao;
/**
* #ORM\Column(type="datetime")
*/
private $data;
/**
* #ORM\OneToMany(targetEntity="SistemaIfnmg\Entity\ReuniaoServidor", mappedBy="reuniaofk")
*/
private $servidores;
public function __construct(){
$this->servidores = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return string
*/
public function getTitulo()
{
return $this->titulo;
}
/**
* #param string $titulo
*/
public function setTitulo($titulo)
{
$this->titulo = $titulo;
}
/**
* #return string
*/
public function getDescricao()
{
return $this->descricao;
}
/**
* #param string $descricao
*/
public function setDescricao($descricao)
{
$this->descricao = $descricao;
}
/**
* #return string
*/
public function getData()
{
return $this->data;
}
/**
* #param string $data
*/
public function setData($data)
{
$this->data = $data;
}
/**
* Add servidores
* #param \SistemaIfnmg\Entity\ReuniaoServidor $servidor
* #return Reuniao
*/
public function addServidor(\SistemaIfnmg\Entity\ReuniaoServidor $servidor){
$this->servidores[] = $servidor;
}
/**
* Remove servidor
*
* #param \SistemaIfnmg\Entity\ReuniaoServidor $servidor
*/
public function removeServidor(\SistemaIfnmg\Entity\ReuniaoServidor $servidor){
$this->servidores->removeElement($servidor);
}
/**
* Get servidores
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getServidores(){
return $this->servidores;
}
}
?>
Servidor.php
<?php
namespace SistemaIfnmg\Entity;
use SistemaIfnmg\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
* #ORM\Table(name="servidor")
*/
class Servidor
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #var integer $id
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nome", type="string", length=255)
*/
private $nome;
/**
* #var string
*
* #ORM\Column(name="sobrenome", type="string", length=255)
*/
private $sobrenome;
/**
* #var string
*
* #ORM\Column(name="cargo", type="string", length=255)
*/
private $cargo;
/**
* #var string
*
* #ORM\Column(name="matricula", type="string", length=255)
*/
private $matricula;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get nome
*
* #return string
*/
public function getNome()
{
return $this->nome;
}
/**
* Set nome
*
* #param string $nome
*/
public function setNome($nome)
{
$this->nome = $nome;
}
/**
* Get sobrenome
*
* #return string
*/
public function getSobrenome()
{
return $this->sobrenome;
}
/**
* Set sobrenome
* #param string $sobrenome
*/
public function setSobrenome($sobrenome)
{
$this->sobrenome = $sobrenome;
}
/**
* Get cargo
*
* #return string
*/
public function getCargo()
{
return $this->cargo;
}
/**
* Set cargo
*
* #param string $cargo
*/
public function setCargo($cargo)
{
$this->cargo = $cargo;
}
/**
* Get matricula
*
* #return string
*/
public function getMatricula()
{
return $this->matricula;
}
/**
* Set matricula
*
* #param string $matricula
*/
public function setMatricula($matricula)
{
$this->matricula = $matricula;
}
}
?>
ReuniadoServidor.php
<?php
namespace SistemaIfnmg\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ReuniaoServidor
*
* #ORM\Table(name="reuniaoservidor", indexes={#ORM\Index(name="fk_Reuniao_has_Servidor_Reuniao1_idx", columns={"reuniaofk"}), #ORM\Index(name="fk_Reuniao_has_Servidor_Servidor1_idx", columns= {"servidorfk"})})
* #ORM\Entity
*/
class ReuniaoServidor
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="SistemaIfnmg\Entity\Reuniao", inversedBy="servidores", cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="reuniaofk", referencedColumnName="id")
* })
*/
private $reuniaofk;
/**
* #ORM\ManyToOne(targetEntity="SistemaIfnmg\Entity\Servidor", inversedBy="servidores")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="servidorfk", referencedColumnName="id")
* })
*/
private $servidorfk;
/**
* Get id
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get reuniaofk
* #return \SistemaIfnmg\Entity\Reuniao
*/
public function getReuniaofk()
{
return $this->reuniaofk;
}
/**
* Set reuniaofk
* #param \SistemaIfnmg\Entity\Reuniao $reuniaofk
* #return ReuniaoServidor
*/
public function setReuniaofk($reuniaofk)
{
$this->reuniaofk = $reuniaofk;
return $this;
}
/**
* Get servidorfk
* #return \SistemaIfnmg\Entity\Servidor
*/
public function getServidorfk()
{
return $this->servidorfk;
}
/**
* Set servidorfk
* #param \SistemaIfnmg\Entity\Servidor $servidorfk
* #return ReuniaoServidor
*/
public function setServidorfk($servidorfk)
{
$this->servidorfk = $servidorfk;
return $this;
}
}
?>
I've been trying to fix this error for a long time, please, help??
Thanks a lot
You don't need the entity that joins Reuniao to Servidor (the ReuniaoServidor entity) as Doctrine takes care of the join table for you. You just need to specify the join columns in the JoinTable mapping.
In Reuniao.php change the mapping of servidores to:
/**
* #ORM\ManyToMany(targetEntity="SistemaIfnmg\Entity\Servidor")
* #ORM\JoinTable(name="reuniao_servidor",
* joinColumns={#ORM\JoinColumn(name="ruuniao_id", referencedColumnName="id")},
* inverseJoinColumns{#ORM\JoinColumn(name="servidor_id", referencedColumnName="id")}
* )
*/
private $servidores;
also add a constructor that initializes the array for the collection
public function __construct()
{
$this->servidores = new ArrayCollection();
}
See https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html#many-to-many-unidirectional

Doctrine Inheritance and user types

im new to Doctrine and ORM in general.
I got 4 user types (Admin, Caretaker, Child, Personal).
They all got some of the same columns (id, name, mail, password, created, type & group)
and they got a few columns special to each of them (Caretaker has a child id etc.)
I'm not quite sure how i should map this.
Like should i make my user types extend the User, giving the Child table the user columns, or what would be best practice here?
I assume the the option to use extend would force some more work when doing a login?
User.php
/**
* #MappedSuperclass
* #Entity #Table(name="users")
*/
class User
{
/**
* #Id #GeneratedValue #Column(type="integer")
* #var int
**/
protected $id;
/**
* #Column(type="string")
* #var string
**/
protected $name;
/**
* #Column(type="string")
* #var string
**/
protected $mail;
/**
* #Column(type="string")
* #var string
**/
protected $password;
/**
* #Column(type="datetime")
**/
protected $created;
/**
* #Column(type="datetime")
**/
protected $lastlogin;
/**
* #ManyToOne(targetEntity="Group")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
protected $group;
/**
* #ManyToOne(targetEntity="Type")
* #JoinColumn(name="type_id", referencedColumnName="id")
*/
protected $type;
public function __construct() {}
public function getId() { return $this->id; }
public function getName() { return $this->name; }
public function getMail() { return $this->mail; }
public function getCreated() { return $this->mail; }
public function getLastLogin() { return $this->lastlogin; }
public function getGroup() { return $this->group; }
public function getType() { return $this->type; }
public function setName($name) { $this->name = $name; }
public function setMail($mail) { $this->mail = $mail; }
public function setCreated() { $this->created = new DateTime("now"); }
public function setLastLogin() { $this->lastlogin = new DateTime("now"); }
public function setGroup($group) { $this->group = $group; }
public function setType($type) { $this->type = $type; }
}
Child.php
// src/Child.php
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity #Table(name="child")
*/
class Child extends User
{
/**
* #Id #OneToOne(targetEntity="User")
* #JoinColumn(name="id", referencedColumnName="id")
**/
protected $id;
/**
* #Column(type="string")
*/
protected $image;
/**
* #ManyToMany(targetEntity="User")
* #JoinTable(name="child_Contacts",
* joinColumns={#JoinColumn(name="child_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="contact_id", referencedColumnName="id")}
* )
*/
protected $currentContacts;
/**
* #OneToMany(targetEntity="Alarm", mappedBy="child")
*/
protected $alarms;
public function __construct()
{
$this->alarms = new ArrayCollection();
}
}
You can easily solve this problem with doctrine and InheritanceType mapping.
Basically, you can do something like this :
/**
* #MappedSuperclass
* #Entity #Table(name="users")
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="discr", type="string")
* #DiscriminatorMap({"Admin" = "Admin", "Caretaker" = "Caretaker", "Child" = "Child", "Personal" = "Personal"})
*/
class User
{
/**
* #Id #GeneratedValue #Column(type="integer")
* #var int
**/
protected $id;
/**
* #Column(type="string")
* #var string
**/
protected $name;
/**
* #Column(type="string")
* #var string
**/
protected $mail;
/**
* #Column(type="string")
* #var string
**/
protected $password;
/**
* #Column(type="datetime")
**/
protected $created;
/**
* #Column(type="datetime")
**/
protected $lastlogin;
/**
* #ManyToOne(targetEntity="Group")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
protected $group;
}
And then, in each 4 different classes,
// src/Child.php
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity #Table(name="child")
*/
class Child extends User
{
/**
* #Id #OneToOne(targetEntity="User")
* #JoinColumn(name="id", referencedColumnName="id")
**/
protected $id;
/**
* #Column(type="string")
*/
protected $image;
/**
* #ManyToMany(targetEntity="User")
* #JoinTable(name="child_Contacts",
* joinColumns={#JoinColumn(name="child_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="contact_id", referencedColumnName="id")}
* )
*/
protected $currentContacts;
/**
* #OneToMany(targetEntity="Alarm", mappedBy="child")
*/
protected $alarms;
public function __construct()
{
$this->alarms = new ArrayCollection();
}
}
The doctrine docs is really good for this problem : http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html
And you don't need an extra check at login because doctrine create automatically the right class for you.

Entity was not found

I am having troubles with only 1 class in symfony2,
Every time i try to use the entity in a template it says the entity was not found.
However everything works perfectly fine on localhost (both dev and prod environment work), but it all stops working when i deploy it on the remote webserver.
I restarted httpd already and tried different methods.
The Entity UserApplication has an association on the Application entity, i am trying to get the name from the application trough the UserApplication in my template file
This is the error message i is throwing,
[ERROR]: An exception has been thrown during the rendering of a
template ("Entity was not found.") in
"MyBundle:Application:applications_user.html.twig" at line 34. with
code: 0 (file: mylocation/20131209193528/app/cache/prod/classes.php,
line: 4485)
Snippet: applications_user.html.twig
{% extends 'MaximCMSBundle:Default:index.html.twig' %}
{% block body %}
<div class="page">
<h3 class="page-header">Applications</h3>
<div class="page-content">
<ul class="menu menu-clean">
{% for application in applications %}
<li>
<span>{{ application.application.name }}</span>
</li>
{% else %}
<p>There are no open applications at the moment</p>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
Entity UserApplication
<?php
namespace MyName\Module\ApplicationBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* UserApplication
*
* #ORM\Table(name="user_application")
* #ORM\Entity
*/
class UserApplication {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="MyName\MyBundle\Entity\User")
*/
protected $user;
/**
* #var json_array $details
*
* #ORM\Column(name="details", type="json_array", nullable=false)
*/
protected $details;
/**
* #var \DateTime $date
*
* #ORM\Column(name="date", type="datetime", nullable=true)
*/
protected $date;
/**
* #var integer $denied
*
* #ORM\Column(name="denied", type="integer", nullable=false)
*/
protected $denied = 0;
/**
* #var Application
*
* #ORM\ManyToOne(targetEntity="Application", inversedBy="userApplications")
*/
protected $application;
/**
* #param Application $application
*/
public function setApplication($application)
{
$this->application = $application;
}
/**
* #return Application
*/
public function getApplication()
{
return $this->application;
}
/**
* #param \DateTime $date
*/
public function setDate($date)
{
$this->date = $date;
}
/**
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* #param int $denied
*/
public function setDenied($denied)
{
$this->denied = $denied;
}
/**
* #return int
*/
public function getDenied()
{
return $this->denied;
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param \MyName\MyBundle\Entity\User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* #return \MyName\MyBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* #param \MyName\MyBundle\Entity\json_array $details
*/
public function setDetails($details)
{
$this->details = $details;
}
/**
* #return \MyName\MyBundle\Entity\json_array
*/
public function getDetails()
{
return $this->details;
}
public function getApplicationEntityName()
{
return "MyNameModuleApplicationBundle:Application";
}
public function __toString()
{
return "";
}
}
Entity Application:
<?php
namespace MyName\Module\ApplicationBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* MyName\Module\ApplicationBundle\Entity\Application
*
* #ORM\Table(name="application")
* #ORM\Entity
*/
class Application
{
const FIELD_NAME = "NAME";
const FIELD_TYPE = "TYPE";
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*
* #var integer $id
*/
protected $id;
/**
* #var Rank
*
* #ORM\ManyToOne(targetEntity="\MyName\MyBundle\Entity\Rank")
* #ORM\JoinColumn(name="rank_id", referencedColumnName="id", nullable=false)
*/
protected $rank;
/**
* #var Website
*
* #ORM\ManyToOne(targetEntity="\MyName\MyBundle\Entity\Website")
* #ORM\JoinColumn(name="website_id", referencedColumnName="id", nullable=false)
*/
protected $website;
/**
* #var string $name
*
* #ORM\Column(name="application_name", type="string", nullable=false)
*/
protected $name;
/**
* #var string $enabled
*
* #ORM\Column(name="application_enabled", type="integer", nullable=false)
*/
protected $enabled = 0;
/**
* #var array $fields
*
* #ORM\Column(name="application_fields", type="json_array", nullable=true)
*/
protected $fields;
/**
*
* #ORM\OneToMany(targetEntity="UserApplication", mappedBy="application")
*/
protected $userApplications;
public function __construct()
{
$this->date = new \DateTime("now");
$this->userApplications = new ArrayCollection();
}
/**
* #param string $enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
}
/**
* #return string
*/
public function getEnabled()
{
return $this->enabled;
}
/**
* #param string $path
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* #return string
*/
public function getPath()
{
return $this->path;
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param \MyName\MyBundle\Entity\Rank $rank
*/
public function setRank($rank)
{
$this->rank = $rank;
}
/**
* #return \MyName\MyBundle\Entity\Rank
*/
public function getRank()
{
return $this->rank;
}
/**
* #param \MyName\MyBundle\Entity\Website $website
*/
public function setWebsite($website)
{
$this->website = $website;
}
/**
* #return \MyName\MyBundle\Entity\Website
*/
public function getWebsite()
{
return $this->website;
}
/**
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #param array $fields
*/
public function setFields($fields)
{
$this->fields = $fields;
}
/**
* #return array
*/
public function getFields()
{
return $this->fields;
}
function __toString()
{
return $this->name;
}
/**
* #param mixed $userApplications
*/
public function setUserApplications($userApplications)
{
$this->userApplications = $userApplications;
}
/**
* #return mixed
*/
public function getUserApplications()
{
return $this->userApplications;
}
}
I apparently had existing records which were conflicting with the application, after deleting those everything worked as supposed to. That was the reason why it was working on the development environment and not in the production.
Thanks for all the support

Mapping FAIL - The entity-class 'PI\UnidadBundle\Entity\HorasPorUnidad' mapping is invalid

I'm having a problem here and I don't know how to fix it. See I have this two entities:
<?php
namespace PI\ProyectoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Event\LifecycleEventArgs;
/**
* #ORM\Entity
* #ORM\Table(name="proyectos")
* #ORM\Entity(repositoryClass="PI\ProyectoBundle\Entity\Repository\ProyectosRepository")
* #ORM\HasLifecycleCallbacks
*/
class Proyectos {
/**
* #ORM\Id
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\Column(type="string", length=45, unique=true, nullable=false)
*/
protected $nombre;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
protected $estado;
/**
* #ORM\Column(type="string", length=45, nullable=false)
*/
protected $pais;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\ClienteBundle\Entity\Clientes", cascade={"all"})
* #ORM\JoinColumn(name="cliente", referencedColumnName="id")
*/
protected $clientes;
/**
* #ORM\ManyToMany(targetEntity="PI\CentroBundle\Entity\Centros", inversedBy="proyectos", cascade={"persist"})
* #ORM\JoinTable(name="proyectos_has_centros",
* joinColumns={#ORM\JoinColumn(name="proyectos_id", referencedColumnName="id"),
* #ORM\JoinColumn(name="proyectos_cliente", referencedColumnName="cliente")},
* inverseJoinColumns={#ORM\JoinColumn(name="centros_id", referencedColumnName="id")}
* )
*/
protected $centros;
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", cascade={"persist"})
* #ORM\JoinTable(name="proyectos_has_system_user",
* joinColumns={#ORM\JoinColumn(name="proyectos_id", referencedColumnName="id"),
* #ORM\JoinColumn(name="proyectos_cliente", referencedColumnName="cliente")},
* inverseJoinColumns={#ORM\JoinColumn(name="system_user_id", referencedColumnName="id")}
* )
*/
protected $ingenieros;
public function __construct() {
$this->centros = new \Doctrine\Common\Collections\ArrayCollection();
$this->ingenieros = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setNombre($nombre) {
$this->nombre = $nombre;
}
public function getNombre() {
return $this->nombre;
}
public function setEstado($estado) {
$this->estado = $estado;
}
public function getEstado() {
return $this->estado;
}
public function setPais($pais) {
$this->pais = $pais;
}
public function getPais() {
return $this->pais;
}
public function setClientes(\PI\ClienteBundle\Entity\Clientes $clientes) {
$this->clientes = $clientes;
}
public function getClientes() {
return $this->clientes;
}
public function setCentros(\PI\CentroBundle\Entity\Centros $centros) {
$this->centros[] = $centros;
}
public function getCentros() {
return $this->centros;
}
public function setIngenieros(\BIT\UserBundle\Entity\User $ingenieros) {
$this->ingenieros[] = $ingenieros;
}
public function getIngenieros() {
return $this->ingenieros;
}
/**
* #ORM\PrePersist
*/
public function prePersist(LifecycleEventArgs $eventArgs) {
$em = $eventArgs->getEntityManager();
$q = $em->createQuery('SELECT MAX(p.id) FROM PIProyectoBundle:Proyectos p');
$id = $q->getSingleResult(\Doctrine\ORM\Query::HYDRATE_SINGLE_SCALAR);
$this->id = $id + 1;
}
}
And this other:
<?php
namespace PI\UnidadBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="horas_por_proyectos")
*/
class HorasPorUnidad {
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", cascade={"all"})
* #ORM\JoinColumn(name="fos_user_user_id", referencedColumnName="id")
*/
protected $fos_user_user_id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\UnidadBundle\Entity\Unidades", cascade={"all"})
* #ORM\JoinColumn(name="fos_user_user_id", referencedColumnName="id")
*/
protected $unidades_id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\CentroBundle\Entity\Centros", cascade={"all"})
* #ORM\JoinColumn(name="centros_id", referencedColumnName="id")
*/
protected $centros_id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\ProyectoBundle\Entity\Proyectos", cascade={"all"})
* #ORM\JoinColumn(name="proyectos_id", referencedColumnName="id")
*/
protected $proyectos_id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\ClienteBundle\Entity\Clientes", cascade={"all"})
* #ORM\JoinColumn(name="proyectos_cliente", referencedColumnName="id")
*/
protected $proyectos_cliente;
/**
* #ORM\Column(type="date")
*/
protected $fecha;
/**
* #ORM\Column(type="integer")
*/
protected $horas;
public function setUserId(\Application\Sonata\UserBundle\Entity\User $user) {
$this->fos_user_user_id = $user;
}
public function getUserId() {
return $this->fos_user_user_id;
}
public function setUnidadesId(\PI\UnidadBundle\Entity\Unidades $unidad) {
$this->unidades_id = $unidad;
}
public function getUnidadesId() {
return $this->unidades_id;
}
public function setCentrosId(\PI\CentroBundle\Entity\Centros $centro) {
$this->centros_id = $centro;
}
public function getCentrosId() {
return $this->centros_id;
}
public function setHoras($cantidad_horas) {
$this->horas = $cantidad_horas;
}
public function getHoras() {
return $this->horas;
}
public function setFecha($fecha) {
$this->fecha = $fecha;
}
public function getFecha() {
return $this->fecha;
}
}
But when I run the task php app/console doctrine:schema:validate I get this errors:
[Mapping] FAIL - The entity-class 'PI\UnidadBundle\Entity\HorasPorUnidad' mapping is invalid:
Cannot map association 'PI\UnidadBundle\Entity\HorasPorUnidad#proyectos_id as identifier, because the target entity 'PI\ProyectoBundle\Entity\Proyectos' also maps an association as identifier.
The join columns of the association 'proyectos_id' have to match to ALL identifier columns of the target entity 'PI\UnidadBundle\Entity\HorasPorUnidad', however 'id, cliente' are missing.
And I don't know how to fix them, so any help from experts? What I need to fix here?
You foget the mappedBy and inversedBy attributes in the ManyToOne assocciation and also check the other side of your assocciations:
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="PI\ClienteBundle\Entity\Clientes",inversedBy="?" cascade={"all"})
* #ORM\JoinColumn(name="cliente", referencedColumnName="id")
*/
protected $clientes;

Persist a clone

In this problem Deep Cloning I thought my issue was due to a deep/shallow copy.
I have vainly tested clone() and unserialize(serialize()) methods.
So I tried to write my own clone function using all setters/getters and then I realized what was really my issue, a persisting one.
The fact is I already succeeded in persisting a clone of my entity, in another context.
The main difference between my two situations is that in one case my original object is already managed by doctrine (this is the case where i'm blocked), and in the second case, my original object is just persisted, I don't have called flush() yet (and it's works fine).
So this is the situation when persist do not persist the many to many relations :
public function duplicateCourseAction(Request $request) {
if ($this->getRequest()->isXmlHttpRequest() == false) {
return new Response("Bad request", 405);
}
$em = $this->getDoctrine()->getManager();
$parameters = $request->request->all();
$course = $em->getRepository('EntTimeBundle:Course')->findOneById($parameters['id']);
$duplicate = clone $course;
$duplicate->setId(null);
$duplicate->setDate(new \DateTime($parameters['date']));
$em->persist($duplicate);
$em->flush();
return new Response("200");
}
And this is the situation whe it's works like a charm
$em->persist($obj);
while ($new_date < $up_to) {
if ($this->isAvailable($holidays, $new_date)) {
$new_course = clone $obj;
$new_course->setDate($new_date);
$new_course->setUuid($uuid);
$new_date = clone $new_date;
$em->persist($new_course);
}
$new_date->modify($modifier);
}
$em->flush();
Why is it working for only one situation ? There are almost identical...
EDIT 1 : Entities Mapping
-Course :
class Course {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=50, unique=true, nullable=true)
*/
protected $name;
/**
* #ORM\JoinColumn(onDelete="CASCADE")
* #ORM\ManyToOne(targetEntity="Ent\HomeBundle\Entity\Campus", inversedBy="courses")
* #Assert\NotBlank
**/
protected $campus;
/**
* #ORM\JoinColumn(onDelete="CASCADE")
* #ORM\ManyToOne(targetEntity="Ent\HomeBundle\Entity\Room", inversedBy="courses")
* #Assert\NotBlank
**/
protected $room;
/**
* #ORM\ManyToMany(targetEntity="Ent\UserBundle\Entity\User", inversedBy="courses", cascade={"persist"})
* #ORM\JoinTable(name="course_teacher",
* joinColumns={#ORM\JoinColumn(name="course_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(name="teacher_id", referencedColumnName="id", onDelete="CASCADE")}
* )
* #Assert\NotBlank
*/
private $teachers;
/**
* #ORM\JoinColumn(onDelete="CASCADE")
* #ORM\ManyToOne(targetEntity="Matter", inversedBy="courses")
* #Assert\NotBlank
**/
protected $matter;
/**
* #ORM\JoinColumn(onDelete="CASCADE")
* #ORM\ManyToOne(targetEntity="\Ent\UserBundle\Entity\Grade", inversedBy="courses")
* #Assert\NotBlank
**/
protected $grade;
/**
* #ORM\Column(type="datetime")
* #Assert\NotBlank
**/
protected $date;
/**
* #ORM\Column(type="time")
* #Assert\NotBlank
**/
protected $duration;
/**
* #ORM\Column(type="string", length=30, nullable=true)
*/
protected $uuid;
/**
* #ORM\ManyToMany(targetEntity="Ent\TimeBundle\Entity\Course", mappedBy="courses")
* #Exclude
*/
protected $alerts;
public function __toString() {
if (empty($this->getName())) {
$string = $this->getMatter().' - '.$this->getRoom().' - ';
foreach ($this->getTeachers() as $count => $teacher) {
$string = $string . $teacher;
if ($count < count($this->getTeachers()) - 1) {
$string = $string . ', ';
}
}
return $string;
} else {
return $this->getName().' - '.$this->getRoom();
}
}
/**
* Constructor
*/
public function __construct() {
$this->teachers = new ArrayCollection();
$this->alerts = new ArrayCollection();
}
public function __clone() {
// $this->id = null;
// $this->teachers = clone $this->teachers;
}
}
-User (Teacher) :
class User implements UserInterface, \Serializable {
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=30)
* #Assert\NotBlank
*/
protected $firstName;
/**
* #ORM\Column(type="string", length=30)
* #Assert\NotBlank
*/
protected $lastName;
/**
* #ORM\Column(type="string", length=70, unique=true)
* #Assert\NotBlank
*/
protected $username;
/**
* #Gedmo\Slug(fields={"username"}, updatable=false)
* #ORM\Column(length=50, unique=true)
*/
protected $slug;
/**
* #ORM\Column(type="string", length=32)
* #Exclude
*/
protected $salt;
/**
* #ORM\Column(type="string", length=40)
* #Exclude
*/
protected $password;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $picture_path;
/**
* #Assert\File(maxSize="10M", mimeTypesMessage="Please upload a valid Image")
*/
protected $picture;
/**
* #ORM\Column(type="string", length=60, unique=true)
* #Exclude
* #Assert\NotBlank
*/
protected $email;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
protected $isActive;
/**
* #ORM\ManyToOne(targetEntity="Group", inversedBy="users")
* #ORM\JoinColumn(name="role_group", referencedColumnName="role", onDelete="CASCADE")
*/
protected $group;
/**
* #ORM\ManyToMany(targetEntity="Ent\HomeBundle\Entity\Campus", inversedBy="users")
* #Exclude
**/
protected $campuses;
/**
* #ORM\OneToMany(targetEntity="\Ent\NewsBundle\Entity\News", mappedBy="user")
* #Exclude
*/
protected $news;
/**
* #ORM\ManyToMany(targetEntity="\Ent\TimeBundle\Entity\Matter", inversedBy="teachers", cascade={"persist"})
* #ORM\JoinTable(name="user_matter",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(name="matter_id", referencedColumnName="id", onDelete="CASCADE")}
* )
*/
protected $matters;
/**
* #ORM\ManyToMany(targetEntity="Ent\UserBundle\Entity\Grade")
* #Assert\NotBlank
* #Exclude
**/
protected $grades;
/**
* #ORM\ManyToMany(targetEntity="Ent\TimeBundle\Entity\Course", mappedBy="teachers")
* #Exclude
**/
protected $courses;
/**
* #ORM\OneToMany(targetEntity="\Ent\TimeBundle\Entity\Alert", mappedBy="teacher")
* #Exclude
**/
protected $alerts;
protected $temp;
public function __construct() {
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
public function __toString() {
return $this->getFullName();
}
}
EDIT 2 : Solution
Thanks to Paul Andrieux this is the function we made to clone my object :
public function course_deep_clone($course) {
$em = $this->getDoctrine()->getManager();
$clone = clone $course;
$clone->setTeachers(array());
$teachers = $course->getTeachers();
foreach ($teachers as $teacher) {
$clone->addTeacher($teacher);
}
return $clone;
}
Thing is that ManyToMany related entities are not cloned, try that:
public function duplicateCourseAction(Request $request) {
if ($this->getRequest()->isXmlHttpRequest() == false) {
return new Response("Bad request", 405);
}
$em = $this->getDoctrine()->getManager();
$parameters = $request->request->all();
$course = $em->getRepository('EntTimeBundle:Course')->findOneById($parameters['id']);
$duplicate = clone $course;
$teachers = $course->getTeachers();
$duplicate->setTeachers($teachers);
$duplicate->setId(null);
$duplicate->setDate(new \DateTime($parameters['date']));
$em->persist($duplicate);
$em->flush();
return new Response("200");
}
This way, you are persisting new relationship and new join table between you two entities
EDIT:
Maybe its a cascading problem, what gives you this ? :
$teachers = $course->getTeachers();
foreach ($teachers as $teacher) {
$teacher->addCourse($duplicate);
$em->persist($teacher);
}

Categories