so, I have multiple entities in my app, between them:
Product* - *Order
User* - 1UserRole
Order
class Order
{
...
/**
* #ManyToMany(targetEntity="Product", inversedBy="orders", cascade={"persist"})
* #JoinTable(
* name="orders_products",
* joinColumns={
* #JoinColumn(name="order_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #JoinColumn(name="product_id", referencedColumnName="id")
* }
* )
*/
private Collection $products;
...
public function __construct()
{
$this->products = new ArrayCollection();
}
...
public function addProduct(Product $product):self
{
$this->products[] = $product;
return $this;
}
}
Product
class Product
{
...
/**
* #ManyToMany(targetEntity="Order", mappedBy="products")
*/
protected Collection $orders;
...
public function __construct()
{
$this->orders = new ArrayCollection();
}
public function addOrder(Order $order): self
{
$this->orders[] = $order;
return $this;
}
}
User
class User
{
/**
* #ManyToOne(targetEntity="UserRole")
* #JoinColumn(name="role_id", referencedColumnName="id")
*/
protected $role;
}
And UserRole:
class UserRole
{
/** #Id #Column(type="integer") #GeneratedValue */
protected $id;
/** #Column(type="string", nullable=false, unique=true, length=20) */
protected $name;
/** #Column(type="integer", unique=true, nullable=false) */
protected $rolePriority;
/**
* Many Users have Many Stores.
* #ManyToMany(targetEntity="UserRoleAction", inversedBy="user_role_actions", fetch="EAGER", cascade={"persist"})
*/
protected Collection $userRoleActions;
/**
* UserRole constructor.
*/
public function __construct()
{
$this->userRoleActions = new ArrayCollection();
}
...
}
Ok so far, my issue is the following, when I try to save a new order that has many selected products:
class OrderService
{
public function createFromRequest(HttpRequest $request)
{
...
$products = $this->entityManager->getRepository(Product::class)->findWhatever(); //products are coming from this without issues.
foreach ($products as $product) {
$order->addProduct($product);
}
$this->entityManager->persist($order);
$this->entityManager->flush();
return $order;
}
}
I get:
Blockquote Expected value of type "UserRole" for association field "User#$role", got "__PHP_Incomplete_Class" instead.
I mean, how is this in any way related with the other entities??? I have no clue where to go to be fair. Any recommendations? Is doctrine doing some absolutely unrelated validation behind the scenes? wth?
Related
I want to create my entities from an existing database, it's an N - N relation which create articlesCategories table.
I currently have 2 entities, Article and Category, and I want to have a ManyToMany bidirectionnal relationship.
But when I try to get article or category with a findByXXX or findOneByXXX method, my ManyToMany attribute is NULL or I have an ORM Exception : Entity 'App\Models\Article' has no field 'categories'. You can therefore not call 'findByCategories' on the entities' repository
Database :
Table article : idArticle, name, description, priceHT, size
Table category : idCategory, name, percentTaxe
Table articlesCategories : idArticle, idCategory
Entities :
Category
/**
* #Entity
* #Table(name="category")
*/
class Category
{
/**
* #var integer
*
* #Id
* #Column(name="idCategory", type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
* #Column(name="percentTaxe",type="decimal", precision=10, scale=0, nullable=false)
*/
private $percentTaxe;
/*
* Many categories have many articles
* #ManyToMany(targetEntity="App\Models\Article", inversedBy="categories")
* #JoinTable(name="articlesCategories",
* joinColumns={#JoinColumn(name="idCategory", referencedColumnName="idCategory")},
* inverseJoinColumns={#JoinColumn(name="idArticle", referencedColumnName="idArticle")}
* )
*/
private $articles;
/*Constructor*/
public function __construct(){
$toto = "toto";
var_dump($toto);
$this->articles = new ArrayCollection();
}
/***************************
Getters / Setters
****************************/
public function getId(){
return $this->id;
}
public function getName(){
return $this->name;
}
public function getPercentTaxe(){
return $this->percentTaxe;
}
public function getArticles(){
return $this->articles;
}
/************************/
public function setId($id){
$this->id = $id;
}
public function setName($name){
$this->name = htmlspecialchars($name);
}
public function setPercentTaxe($percentTaxe){
$this->percentTaxe = htmlspecialchars($percentTaxe);
}
public function setArticles(\Doctrine\Common\Collections\Collection $articles)
{
$this->articles = $articles;
}
/***************************
Getters / Setters
****************************/
public function addArticle(App\Models\Article $article)
{
var_dump($article);
$article->addCategory($this); // synchronously updating inverse side
$this->articles[] = $article;
}
Article
/**
* #Entity
* #Table(name="article")
*/
class Article
{
/**
* #var integer
*
* #Id
* #Column(name="idArticle", type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
* #Column(name="description",type="string", nullable=true)
*/
private $description;
/**
* #var string
* #Column(name="priceHT",type="decimal", precision=10, scale=3, nullable=false)
*/
private $priceHT;
/**
* #var string
* #Column(name="size", type="string", length=3, nullable=true)
*/
private $size;
/*
* Many articles have many categories
* #ManyToMany(targetEntity="App\Models\Category", inversedBy="articles")
* #JoinTable(name="articlesCategories",
* joinColumns={#JoinColumn(name="idArticle", referencedColumnName="idArticle")},
* inverseJoinColumns={#JoinColumn(name="idCategory", referencedColumnName="idCategory")}
* )
*/
private $categories;
/*Constructor*/
public function __construct(){
echo"tata";
$this->categories = new ArrayCollection();
echo"tata";
}
/***************************
Getters / Setters
****************************/
public function getId(){
return $this->id;
}
public function getName(){
return $this->name;
}
public function getDescription(){
return $this->description;
}
public function getPriceHT(){
return $this->priceHT;
}
public function getSize(){
return $this->size;
}
public function getCategories(){
return $this->categories;
}
/************************/
public function setId($id){
$this->id = $id;
}
public function setName($name){
$this->name = htmlspecialchars($name);
}
public function setDescription($description){
$this->description = htmlspecialchars($description);
}
public function setPriceHT($priceHT){
$this->priceHT = htmlspecialchars($priceHT);
}
public function setSize($size){
$this->size = htmlspecialchars($size);
}
public function setCategories($categories){
$this->categories = $categories;
}
/***************************
Getters / Setters
****************************/
public function addCategory(App\Models\Category $category)
{
$category->addArticle($this); // synchronously updating inverse side
$this->categories[] = $category;
}
/************************/
public function hydrate($data)
{
foreach($data as $key => $value)
{
// Get back the setter name wich correspond to the attribute
$method = 'set'.ucfirst($key);
// if the good setter exist.
if(methodexists($this, $method))
{
$this->$method($value);
}
}
}
}
Manager
/**
* #param category : category of article we want
* #return an array of Article object or null
*/
public function getArticlesByCategory($categoryName)
{
$articles = NULL;
$repository = $this->getEntityManager()->getRepository("App\Models\Category");
$category = $repository->findOneByName($categoryName);
var_dump($category);
if($category != NULL)
{
$articles = $category->getArticles();
}
return $articles;
}
And when I var_dump my $category, I have : class App\Models\Category#122 (4) { private $id => int(2) private $name => string(7) "clothes" private $percentTaxe => string(2) "20" private $articles => NULL }
I found my categories and articles are null instead of to be an empty array because of Doctrine create instances of mapped entities without invoking constructor but I don't understand why It doesn't populate it.
I just use Doctrine2, I don't use symfony.
First, you have an error at your annotations on categories and articles fields of both entities. To be valid they should start with /** not /*.Change:
/*
* Many categories have many articles
to
/**
* Many categories have many articles
Same for $categories field of Article Entity.
Also change one of the fields(articles or categories) to be the inverse side of the relation, e.g.
inversedBy="categories"
to
mappedBy="categories"
On the other part of your question, default EntityRepository find methods(findBy, findOneBy) of the does not support filter by many to many relation(at least not yet). You will have to do the extra effort and use createQueryBuilder, e.g.:
$qb = $doctrine->getRepository(Article::class)->createQueryBuilder('a');
$qb->select(
'a',
'cat'
)
->innerJoin( 'a.categories', 'cat' )
->where('cat.id =1');
And better create your own ArticleRepository and CategoryRepository and define your find methods there. 7.8.8. Custom repositories
I am new with Symfony. I am working with version 3. I simplified my example. I have 3 Tables, for this tables I created a class for each one.
Table "Person": id | name
Table "Group": id | groupname
Table "PersonGroup": id | person | group
Every Person could be in several groups and every groups can have several persons. In the table PersonGroup I connect the persons with the groups. In my Controller I want to request in which group the selected person is. But in the Dump I only have the data from the PersonGroup table and not the details from the Group (in this example the name):
PersonGroup {#485 ▼
-id: 5
-person: Person {#456 ▼
-id: 4
-name: "Adam"
-personGroups: PersistentCollection {#445 ▶}
}
-group: Group {#486 ▼
+__isInitialized__: false
-id: 5
-name: null
-personGroups: null
…2
}
}
My Controller:
/**
* #Route("/person/{personId}", name="personController")
*/
public function showAction($personId)
{
$em = $this->getDoctrine()->getManager();
$item = $em->getRepository('AppBundle:Person')
->findOneBy(['id' => $personId]);
foreach ($person->getPersonGroup() as $personGroup) {
dump($personGroup);
}
return $this->render('person/detail.html.twig', [
'person' => $person
]);
}
Person class / entity:
class Person
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PersonGroup", mappedBy="person")
*/
private $personGroups;
/**
* Item constructor.
*/
public function __construct()
{
$this->personGroups= new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return ArrayCollection*
*/
public function getPersonGroups()
{
return $this->personGroups;
}
}
Group class/Entity:
class Group
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PersonGroup", mappedBy="group")
*/
private $personGroups;
/**
* Item constructor.
*/
public function __construct()
{
$this->personGroups= new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return ArrayCollection*
*/
public function getPersonGroups()
{
return $this->personGroups;
}
}
PersonGroup class / entity:
class PersonGroup
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Person", inversedBy="group")
* #ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Group", inversedBy="person")
* #ORM\JoinColumn(nullable=false)
*/
private $group;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return Person
*/
public function getPerson()
{
return $this->person;
}
/**
* #param Person $person
*/
public function setPerson(Person $person)
{
$this->person = $person;
}
/**
* #return Group
*/
public function getGroup()
{
return $this->group;
}
/**
* #param Group $group
*/
public function setGroup(Group $group)
{
$this->group = $group;
}
}
You can access to your Group entity from PersonGroup
/**
* #Route("/person/{personId}", name="personController")
*/
public function showAction($personId)
{
$em = $this->getDoctrine()->getManager();
$item = $em->getRepository('AppBundle:Person')
->findOneBy(['id' => $personId]);
foreach ($person->getPersonGroup() as $personGroup) {
dump($personGroup->getGroup());
}
return $this->render('person/detail.html.twig', [
'person' => $person
]);
}
But you should create a custom function in Group repository and Person repository to retrieve the correct entity.
EDIT
If you want te retrieve all the Group entity you should add a parameter fetch="EAGER" to your relations, it will automatically do aan innerJoin on your relation.
class PersonGroup
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Person", inversedBy="group", fetch="EAGER")
* #ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Group", inversedBy="person", fetch="EAGER")
* #ORM\JoinColumn(nullable=false)
*/
private $group;
For example if you want to get All Groups from a Person you can do a custom repository function.
Ex:
<?php
namespace AppBundle\Repository;
use AppBundle\Entity\Person;
/**
* GroupRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class GroupRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPerson(Person $person){
return $this->createQueryBuilder('g')
->leftJoin('g.personGroups', 'pg')
->leftJoin('pg.person', 'p')
->where('p.id = :personId')
->setParameter('personId', $person->getId())
->getQuery()->getResult();
}
}
Here is my Insert Query, how can I tell that, created_at(current time-stamp), is_active(default 1) set in the mysql db structure needs to be taken.
When I omit the $question->setCreatedAt($this->createdAt); in the insert operation it shows me an Integrity constraint violation, do you know what is the issue?
In the Questions table:
question:
id
question
created_by
created_at
modified_by
modified_at
is_Active
Entity:
<?php
namespace Library\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Base class for all the Entities
* This class maps id, active, created and modified columns
*
* #author
*/
/**
* #ORM\MappedSuperclass
*/
class BaseEntity {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id", type="integer")
* #var integer
*/
protected $id;
/**
* #ORM\Column(name="is_active", type="boolean")
* #var boolean
*/
protected $active;
/**
* #ORM\Column(name="created_at", type="datetime")
* #var datetime
*/
protected $createdAt;
/**
* #ORM\Column(name="created_by", type="integer", nullable=true)
* #var integer
*/
protected $createdBy;
/**
* #ORM\Column(name="modified_at", type="datetime")
* #var datetime
*/
protected $modifiedAt;
/**
* #ORM\Column(name="modified_by", type="integer")
* #var integer
*/
protected $modifiedBy;
public function getId() {
return $this->id;
}
public function getActive() {
return $this->active;
}
public function getCreatedAt() {
return $this->createdAt;
}
public function getCreatedBy() {
return $this->createdBy;
}
public function getModifiedAt() {
return $this->modifiedAt;
}
public function getModifiedBy() {
return $this->modifiedBy;
}
public function setId($id) {
$this->id = $id;
}
public function setActive($active) {
$this->active = $active;
}
public function setCreatedAt($createdAt) {
$this->createdAt = $createdAt;
}
public function setCreatedBy($createdBy) {
$this->createdBy = $createdBy;
}
public function setModifiedAt($modifiedAt) {
$this->modifiedAt = $modifiedAt;
}
public function setModifiedBy($modifiedBy) {
$this->modifiedBy = $modifiedBy;
}
}
This is my Question Entity:
<?php
namespace Survey\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Library\Entity\BaseEntity;
use Survey\Entity\Survey;
/**
* Description of Survey Questions
*
* #author Mubarak
*/
/**
* #ORM\Entity
* #ORM\Table(name="survey_questions")
*/
class Question extends BaseEntity{
/**
* #ORM\Column(name="question", type="string")
* #var string
*/
protected $question;
/**
* #ORM\ManyToOne(targetEntity="Survey\Entity\Survey", inversedBy="questions")
* #ORM\JoinColumn(name="survey_id", referencedColumnName="id")
*/
private $surveys;
public function getQuestion() {
return $this->question;
}
public function setQuestion($question) {
$this->question = $question;
}
public function getSurveys() {
return $this->surveys;
}
// public function setSurveys(ArrayCollection $survey) {
public function setSurveys(Survey $surveys = null) {
$this->surveys = $surveys;
}
// public function __toString() {
// return __CLASS__ . ": [id: {$this->id}, name: {$this->name}]";
// }
}
Here is my insert Operation:
public function insertQuestion($userId, $survey, $questionArr) {
try{
$question = new Question();
$question->setQuestion($questionArr['question']);
$question->setSurveys($survey);
$question->setActive(1);
$question->setCreatedBy($userId);
$question->setCreatedAt($this->createdAt);
$question->setModifiedBy($userId);
$question->setModifiedAt($this->modifiedAt);
$this->entityManager->persist($question);
$this->entityManager->flush();
return $question;
}catch(Exception $ex){
throw new Exception("Couldnt insert the question");
}
}
This is Ok, its working properly, but i dont want to insert the Created_at, modified_at
public function insertQuestion($userId, $survey, $questionArr) {
try{
$question = new Question();
$question->setQuestion($questionArr['question']);
$question->setSurveys($survey);
$question->setActive(1);
$question->setCreatedBy($userId);
$question->setModifiedBy($userId);
$this->entityManager->persist($question);
$this->entityManager->flush();
return $question;
}catch(Exception $ex){
throw new Exception("Couldnt insert the question");
}
}
If you want to set default values it is best to set them in your object model where possible.
/**
* #ORM\Column(name="is_active", type="boolean")
* #var boolean
*/
protected $active = true;
For time-stamps though it is a bit of a different story...
I would suggest to take a look at the Gedmo doctrine extensions library which includes solutions for createdAt and other common columns for your model. No need to reinvent the wheel... .
is regarding an association One-To-Many in the same table, but in MongoDB.
class Component
{
...
/**
* #MongoDB\ReferenceMany(
* discriminatorMap={
* "component"="Component"
* },
* inversedBy="components.id",
* cascade={"persist", "remove", "refresh", "merge"}
* )
*
*/
protected $components;
public function __construct()
{
$this->components = new ArrayCollection();
}
/**
* Add components
*
* #param $component
*/
public function addComponents(Component $component)
{
if(!$this->components->contains($component)){
$this->components->add($component);
}
}
...
}
This associates the components me no problem, I look at the collection and actually associates me, but when I try to regain the components, $ this->components is not an ArrayCollection, but a Object Component
any ideas?
It was resolved ...
/**
* #MongoDB\ReferenceOne(targetDocument="Component", inversedBy="children", cascade={"all"})
*/
public $parent;
/**
* #MongoDB\ReferenceMany(targetDocument="Component", mappedBy="parent", cascade={"all"})
*/
public $children;
public function __construct()
{
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addChild(component $child)
{
if(!$this->children->contains($child)){
$child->parent = $this;
$this->children->add($child);
}
}
/**
* Get children
*
* #return Doctrine\Common\Collections\ArrayCollection $children
*/
public function getComponents()
{
return $this->children;
}
Solved by adding a conditional when adding a new entity to the database, it checks if the entity is not null... apparently there was null entities trying to get saved. Now the controller code looks like this:
...
$ciudades_id = explode(';', $this->getRequest()->getParam('ciudades_id'));
foreach($ciudades_id as $ciudad_id){
$ciudad = $this->_em->find("Application_Model_Ciudades", intval($ciudad_id));
if($ciudad!= null){
$carrera->getCiudad()->add($ciudad);
}
}
$instituciones_id = explode(';', $this->getRequest()->getParam('instituciones_id'));
foreach($instituciones_id as $institucion_id){
$institucion = $this->_em->find("Application_Model_Instituciones", intval($institucion_id));
if($institucion != null){
$carrera->getInstituciones()->add($institucion);
}
}
...
Thanks to the guys that helped at #doctrine IRC channel :)
This is my problem... I got an entity called "Carreras" (carreers) that has some associations, and the new carreers are added to the database with a web form. A carreer for me is a test, which has questions and other atttributes, and the user can select the cities and institutions that apply for that test.
So i'm getting this error when i try to save new data on the entity:
An error occurred
Application error
Exception information:
Message: A new entity was found through the relationship
'Application_Model_Carreras#ciudad' that was not configured
to cascade persist operations for entity: Doctrine\ORM\UnitOfWork#.
Explicitly persist the new entity or configure cascading persist
operations on the relationship. If you cannot find out which entity
causes the problem implement 'Application_Model_Ciudades#__toString()'
to get a clue.
This is the model for "Carreras"
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity
* #Table(name="carreras")
*/
class Application_Model_Carreras
{
/**
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/** #Column(type="string") */
private $nombre;
/**
* #ManyToMany(targetEntity="Application_Model_PruebasCarrera")
* #JoinTable(name="Carreras_PruebasCarrera",
* joinColumns={#JoinColumn(name="carreras_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="pruebascarrera_id", referencedColumnName="id")}
* )
*/
private $pruebas;
/** #Column(type="integer") */
private $valor;
/** #Column(type="date") */
private $fechainicio;
/** #Column(type="date") */
private $fechafin;
/**
* This association causes error
* #ManyToMany(targetEntity="Application_Model_Ciudades")
* #JoinTable(name="carrera_ciudades",
* joinColumns={#JoinColumn(name="carrera_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="ciudad_id", referencedColumnName="id")}
* )
*/
private $ciudad;
/**
* #ManyToMany(targetEntity="Application_Model_Instituciones")
* #JoinTable(name="carrera_instituciones",
* joinColumns={#JoinColumn(name="carrera_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="institucion_id", referencedColumnName="id")}
* )
*/
private $instituciones;
public function __construct()
{
$this->pruebas = new ArrayCollection();
$this->ciudad = new ArrayCollection();
$this->instituciones = new ArrayCollection();
}
public function setNombre($nombre){
$this->nombre = $nombre;
}
public function setValor($valor){
$this->valor = $valor;
}
public function setFechainicio($fechainicio){
$this->fechainicio = $fechainicio;
}
public function setFechafin($fechafin){
$this->fechafin = $fechafin;
}
public function getCiudad(){
return $this->ciudad;
}
public function getPruebas(){
return $this->pruebas;
}
public function getInstituciones(){
return $this->instituciones;
}
}
Now the action at controller:
/*
* This is an action for adding a new career
*/
public function agregarAction()
{
$formtest = new Admin_Form_AgregarCarrera();
$this->view->formtest = $formtest;
if ($this->getRequest()->isPost() && $this->view->formtest->isValid($this->_getAllParams()))
{
/*
* If the form is okay creating new Carreer model object
* This model has some attributes and three associations (for now)
* you can see them later in detail
*/
$carrera = new Application_Model_Carreras();
$carrera->setNombre($this->getRequest()->getParam("nombre"));
$carrera->setValor($this->getRequest()->getParam("valor"));
$carrera->setFechainicio(new \DateTime($this->getRequest()->getParam("fechainicio")));
$carrera->setFechafin(new \DateTime($this->getRequest()->getParam("fechafin")));
/*
* This is the first association. It's working fine (for now)
*/
$pruebas = $this->getRequest()->getParam("pruebas");
foreach($pruebas as $prueba){
if($prueba != '0'){
$tmp = $this->_em->find("Application_Model_PruebasCarrera", $prueba);
$carrera->getPruebas()->add($tmp);
}
}
/*
* This is the second associations, i'm getting the error with this one
*/
$ciudades_id = explode(';', $this->getRequest()->getParam('ciudades_id'));
foreach($ciudades_id as $ciudad_id){
$ciudad = $this->_em->find("Application_Model_Ciudades", intval($ciudad_id));
$carrera->getCiudad()->add($ciudad);
}
/*
* This is the third one. Nothing to say about this.
*/
$instituciones_id = explode(';', $this->getRequest()->getParam('instituciones_id'));
foreach($instituciones_id as $institucion_id){
$institucion = $this->_em->find("Application_Model_Instituciones", intval($institucion_id));
$carrera->getInstituciones()->add($institucion);
}
$this->_em->persist($carrera);
$this->_em->flush();
//$this->redirector->gotoSimpleAndExit('index','Carrera','admin');
}
}
Well i don't know what else to show... please comment if you can help me :)
--edit
I added cascade={"persist"} in the associations of the model "Carreras" and the error changed:
An error occurred
Application error
Exception information:
Message: Class Doctrine\ORM\UnitOfWork is not a
valid entity or mapped super class.
Now this is "Ciudades" model, it stores the cities available for the test and is associated with the institutions that exist on every city.
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity
* #Table(name="ciudades")
*/
class Application_Model_Ciudades {
/**
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/** #Column(type="string") */
private $ciudad;
/** #Column(type="string") */
private $departamento;
/** #Column(type="string") */
private $pais;
/**
* #ManyToMany(targetEntity="Application_Model_Instituciones")
* #JoinTable(name="Ciudades_Instituciones",
* joinColumns={#JoinColumn(name="ciudades_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="instituciones_id", referencedColumnName="id")}
* )
*/
private $instituciones;
public function __construct()
{
$this->instituciones = new ArrayCollection();
}
public function getCiudad(){
return $this->ciudad;
}
public function getId(){
return $this->id;
}
public function getInstituciones(){
return $this->instituciones;
}
}
Now this is "Instituciones" Model, it stores the institutions available for the tests.
/**
* #Entity
* #Table(name="instituciones")
*/
class Application_Model_Instituciones {
/**
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/** #Column(type="string") */
private $nombre;
public function getId(){
return $this->id;
}
public function getNombre(){
return $this->nombre;
}
}
Now this is "PruebasCarrera" Model, for me this model entity stores the questions of the tests, and every question can have a partner who supports the question:
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity
* #Table(name="pruebas_carrera")
*/
class Application_Model_PruebasCarrera extends Application_Model_PruebasBase{
/**
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/**
* #ManyToMany(targetEntity="Application_Model_Patrocinadores")
* #JoinTable(name="pruebascarrera_patrocinadores",
* joinColumns={#JoinColumn(name="pruebas_id", referencedColumnName="id", unique="true")},
* inverseJoinColumns={#JoinColumn(name="patrocinadores_id", referencedColumnName="id", unique=false)}
* )
*/
protected $patrocinadores;
/** #Column(type="string") */
private $respuesta;
public function __construct() {
$this->patrocinadores = new ArrayCollection();
}
public function setRespuesta($respuesta){
$this->respuesta = $respuesta;
}
public function getPatrocinadores(){
return $this->patrocinadores;
}
public function getId(){
return $this->id;
}
public function getRespuesta(){
return $this->respuesta;
}
}
Please show code of related entities:
Application_Model_Ciudades
Application_Model_PruebasCarrera
Application_Model_Instituciones
At this moment look https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-associations.html#transitive-persistence-cascade-operations
At this moment i think you should add cascade={"persist"} to the Application_Model_Ciudades entity.