I'm trying remove a registry from my database using doctrine 2, but I'm getting the follow error:
Catchable fatal error: Argument 1 passed to Doctrine\ORM\Mapping\DefaultQuoteStrategy::getJoinTableName() must be an array, null given, called in /home/triangulum/www/pedal/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1020 and defined in /home/triangulum/www/pedal/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php on line 86
I have 3 tables:
grupo = id, name
permissao = id, name
grupo_permissao = grupo_id, permissao_id
My entitys:
Grupo:
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="grupo")
* #ORM\Entity(repositoryClass="User\Entity\GrupoRepository")
*/
class Grupo {
public function __construct($options=null) {
Configurator::configure($this, $options);
$this->permissoes = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
* #var int
*/
protected $id;
/**
* #ORM\Column(type="text")
* #var string
*/
protected $nome;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Permissao", mappedBy="grupo", cascade={"remove"})
*/
protected $permissoes;
public function getPermissoes()
{
return $this->permissoes;
}
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function toArray()
{
return array
(
'id' => $this->getId(),
'nome' => $this->getNome()
);
}
}
?>
Permissao:
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="permissao")
* #ORM\Entity(repositoryClass="User\Entity\PermissaoRepository")
*/
class Permissao {
public function __construct($options=null) {
Configurator::configure($this, $options);
$this->grupos = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
* #var int
*/
protected $id;
/**
* #ORM\Column(type="text")
* #var string
*/
protected $nome;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Grupo", inversedBy="permissao", cascade={"persist", "remove"})
* #ORM\JoinTable(name="grupo_permissao",
* joinColumns={#ORM\JoinColumn(name="permissao_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="grupo_id", referencedColumnName="id")}
* )
*/
protected $grupos;
public function getGrupos() {
return $this->grupos;
}
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function toArray()
{
return array
(
'id' => $this->getId(),
'nome' => $this->getNome()
);
}
}
?>
remove:
public function delete($id)
{
$entity = $this->entityManager->find('User\Entity\Grupo', $id);
if($entity)
{
$this->entityManager->remove($entity);
$this->entityManager->flush();
return $id;
}
}
What am I doing wrong?
I think you have a problem with your mappedBy and inversedBy attributes in the manyToMany annotations. They should match the other entities property name, grupos and permissoes. Try this:
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Permissao", mappedBy="grupos", cascade={"remove"})
*/
protected $permissoes;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Grupo", inversedBy="permissoes", cascade={"persist", "remove"})
* #ORM\JoinTable(name="grupo_permissao",
* joinColumns={#ORM\JoinColumn(name="permissao_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="grupo_id", referencedColumnName="id")}
* )
*/
protected $grupos;
Related
The project works with multiple user logins (plumber, builder), the relevant information for each entity is saved in their respective tables. The structure for them is supplied below.
We've been storing the information for suppliers and have now gathered a few hundred entries. Suppliers are now requiring a login to access the system.
The current flow with the discriminator map is it creates an entry in the Users table and then saves in the respective user type table with the id being that of the user.id.
User.id = 5 => plumber.id = 5
User.id = 6 => builder.id = 6
User.id = 7 => plumber.id = 7
Suppliers have had their own table with their own incrementing ids which would cause clashes with the DiscriminatorMap(). Is there a way to have suppliers be unique and connect on a supplier.user_id instead of supplier.id, like the other tables?
<?php
namespace Project\Entities;
abstract class BaseEntity
{
public static $idCol = 'id';
public static $joins = [];
public static $orderBy = [];
}
?>
<?php
namespace Project\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping AS ORM;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
/**
* #ORM\Entity(repositoryClass="Project\Repositories\User\UserRepository")
* #ORM\Table(name="user")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"user"="User", "plumber"="Plumber", "builder"="Builder"})
* #ORM\HasLifecycleCallbacks()
*/
class User extends BaseEntity implements Authenticatable
{
use \LaravelDoctrine\ORM\Auth\Authenticatable;
use \Project\Entities\Traits\HasContactDetails;
const TYPE_USER = "user";
const TYPE_PLUMBER = "plumber";
const TYPE_BUILDER = "builder";
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #var int
*/
protected $id;
/**
* #ORM\Column(type="string", unique=true, nullable=false)
* #var string
*/
protected $login;
/**
* #ORM\Column(type="text")
* #var string
*/
protected $password;
/**
* #return int
*/
public function getId() {
return $this->id;
}
/**
* #return string
*/
public function getLogin() {
return $this->login;
}
/**
* #param string $login
*/
public function setLogin($login) {
$this->login = $login;
}
public function getAuthPassword() {
return $this->password;
}
/**
* Encrypt password when inserting
* #ORM\PrePersist
*/
public function onPrePersist() {
$this->encryptPassword();
}
/**
* Encrypt password when updating
* #ORM\PreUpdate
*/
public function onPreUpdate(\Doctrine\ORM\Event\PreUpdateEventArgs $event) {
if ($event->hasChangedField('password')) {
$this->encryptPassword();
}
}
/**
*
* #return string
*/
public function getType() {
if ($this instanceof \Project\Entities\Plumber) {
return self::TYPE_PLUMBER;
}
if ($this instanceof \Project\Entities\Builder) {
return self::TYPE_BUILDER;
}
return self::TYPE_USER;
}
public function getAuthIdentifierName() {
return "login";
}
.....
}
?>
User roles extending
<?php
namespace Project\Entities;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity(repositoryClass="Project\Repositories\Plumber\PlumberRepository")
* #ORM\Table(name="plumber")
*/
class Plumber extends User
{
.....
}
?>
<?php
namespace Project\Entities;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity(repositoryClass="Project\Repositories\Builder\BuilderRepository")
* #ORM\Table(name="builder")
*/
class Builder extends User
{
.....
}
?>
The current supplier entity.
<?php
namespace Project\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity(repositoryClass="Project\Repositories\Supplier\SupplierRepository")
* #ORM\Table(name="supplier")
*/
class Supplier extends BaseEntity
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #var int
*/
protected $id;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="Region")
* #var Region
*/
protected $region;
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
public function getRegion() {
return $this->region;
}
public function setId($id) {
$this->id = $id;
}
public function setName($name) {
$this->name = $name;
}
/**
* #param Region $region
*/
public function setRegion($region) {
$this->region = $region;
}
.....
}
?>
I'm building an app that deals with givers and companies, that own givers. Both inherit a super-class called "Organization".
I want to add an unidirectional ManyToMany relationship between them, but when I ask doctrine to implement the database, and hydrate it with fixtures, I can't retrieve the givers owned by a company.
Doctrine hasn't even created a giver_company table whatsoever which could contain the relationship information as it is supposed to do.
Here is my code:
Organization
<?php
// src/Entity/Chain/Organization.php
namespace App\Entity\Chain;
use App\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"association" = "Association", "super_association" = "SuperAssociation", "company" = "Company", "giver" = "Giver"})
*/
abstract class Organization
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $address;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $city;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $zipcode;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $SIREN;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $phone;
/**
* #ORM\OneToOne(targetEntity="App\Entity\Photo")
*/
private $photo;
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="memberOf")
*/
private $members ;
/**
* Organization constructor.
*/
public function __construct()
{
$this->members = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name): void
{
$this->name = $name;
}
public function getAddress()
{
return $this->address;
}
/**
* #param mixed $address
*/
public function setAddress($address): void
{
$this->address = $address;
}
public function getCity()
{
return $this->city;
}
/**
* #param mixed $city
*/
public function setCity($city): void
{
$this->city = $city;
}
public function getZipcode()
{
return $this->zipcode;
}
/**
* #param mixed $zipcode
*/
public function setZipcode($zipcode): void
{
$this->zipcode = $zipcode;
}
public function getSIREN()
{
return $this->SIREN;
}
/**
* #param mixed $SIREN
*/
public function setSIREN($SIREN): void
{
$this->SIREN = $SIREN;
}
public function getPhone()
{
return $this->phone;
}
/**
* #param mixed $phone
*/
public function setPhone($phone): void
{
$this->phone = $phone;
}
public function getPhoto()
{
return $this->photo;
}
/**
* #param mixed $photo
*/
public function setPhoto($photo): void
{
$this->photo = $photo;
}
public function getMembers()
{
return $this->members;
}
public function addMember(User $member)
{
if (!$this->members->contains($member)) {
$this->members->add($member);
}
}
public function removeMember(User $member){
$this->members->remove($member);
}
}
Giver
<?php
// src/Entity/Chain/Giver.php
namespace App\Entity\Chain;
use App\Entity\Photo;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
*/
class Giver extends Organization
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $status ;
/**
* Giver constructor.
*/
public function __construct()
{
parent::__construct();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getStatus()
{
return $this->status;
}
/**
* #param mixed $status
*/
public function setStatus($status): void
{
$this->status = $status;
}
}
Company
<?php
// src/Entity/Chain/Company.php
namespace App\Entity\Chain;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
*/
class Company extends Organization
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, name="company_type")
*/
private $type ;
/*
* #ORM\ManyToMany(targetEntity="App\Entity\Chain\Giver")
*/
private $givers ;
/**
* Company constructor.
*/
public function __construct()
{
parent::__construct();
$this->givers = new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
*/
public function setType($type): void
{
$this->type = $type;
}
public function getGivers()
{
return $this->givers;
}
public function addGiver(Giver $opening)
{
if (!$this->givers->contains($opening)) {
$this->givers->add($opening);
}
}
public function removeGiver(Giver $opening){
$this->givers->remove($opening);
}
}
Your DocBlock for givers in Company is missing an "*" at the beginning. PHPDoc
Change:
/*
* #ORM\ManyToMany(targetEntity="App\Entity\Chain\Giver")
*/
private $givers ;
to
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Chain\Giver")
*/
private $givers ;
I mean I have these two classes (one to many relationship). As you can appreciate in both I have included cascade={"persist"}.
namespace Project\FrontendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="task")
*/
class Task
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, name="description", nullable=true)
*/
protected $description;
/**
* #ORM\OneToMany(targetEntity="Tag", mappedBy="task", cascade={"persist"})
**/
protected $tags;
/*************************************/
public function __toString()
{
return $this->description;
}
/**
* Constructor
*/
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
* #return Task
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Add tags
*
* #param \Project\FrontendBundle\Entity\Tag $tags
* #return Task
*/
public function addTag(\Project\FrontendBundle\Entity\Tag $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \Project\FrontendBundle\Entity\Tag $tags
*/
public function removeTag(\Project\FrontendBundle\Entity\Tag $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
namespace Project\FrontendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="tag")
*/
class Tag
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, name="name", nullable=true)
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="Task", inversedBy="tags", cascade={"persist"})
* #ORM\JoinColumn(name="task_id", referencedColumnName="id")
**/
private $task;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Tag
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set task
*
* #param \Project\FrontendBundle\Entity\Task $task
* #return Tag
*/
public function setTask(\Project\FrontendBundle\Entity\Task $task = null)
{
$this->task = $task;
return $this;
}
/**
* Get task
*
* #return \Project\FrontendBundle\Entity\Task
*/
public function getTask()
{
return $this->task;
}
}
In my controller I have this:
$task = new Task();
$tag = new Tag();
$task->addTag($tag);
$em = $this->getDoctrine()->getManager();
$em->persist($item);
$em->flush();
but the foreign key is always NULL, why?
I think in the Task class, the addTag and removeTag should look like this:
public function addTag($tag)
{
$tag->setTask($this);
$this->tags->add($tag);
}
public function removeTag($tag)
{
$tag->setTask(null);
$this->tags->removeElement($tag);
}
Or if you want to add and remove many tags in one function call use these:
public function addTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setTask($this);
$this->tags->add($tag);
}
}
public function removeTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setTask(null);
$this->tags->removeElement($tag);
}
}
I have the following:
User have one group, group can have many users
User
<?php namespace Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_USR")
* #ORM\Entity
* #package Application\Model
*/
class User
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="USR_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="USR_LOGIN", type="string")
*/
protected $login;
/**
* #var string
* #ORM\Column(name="USR_CODE", type="string")
*/
protected $code;
/**
* #var int
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $groupId;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $groupCode;
/**
* #var User\Group
* #ORM\ManyToOne(targetEntity="Application\Model\User\Group",fetch="EAGER")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $group;
/**
* #var Event
* #ORM\OneToMany(targetEntity="Application\Model\Event", mappedBy="user")
* #ORM\JoinColumn(name="USR_ID", referencedColumnName="USR_ID")
*/
protected $events;
/**
* Constructor
*/
public function __construct()
{
$this->events = new Collections\ArrayCollection();
}
/**
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* #param string $code
* #return User
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return Event
*/
public function getEvents()
{
return $this->events;
}
/**
* #param Event $events
* #return User
*/
public function setEvents($events)
{
$this->events = $events;
return $this;
}
/**
* #return User\Group
*/
public function getGroup()
{
return $this->group;
}
/**
* #param User\Group $group
* #return User
*/
public function setGroup($group)
{
$this->group = $group;
return $this;
}
/**
* #return string
*/
public function getGroupCode()
{
return $this->groupCode;
}
/**
* #param string $groupCode
* #return User
*/
public function setGroupCode($groupCode)
{
$this->groupCode = $groupCode;
return $this;
}
/**
* #return int
*/
public function getGroupId()
{
return $this->groupId;
}
/**
* #param int $groupId
* #return User
*/
public function setGroupId($groupId)
{
$this->groupId = $groupId;
return $this;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
* #return User
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* #param string $login
* #return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
}
Group
<?php namespace Application\Model\User;
use Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User group model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_GRP")
* #ORM\Entity
* #package Application\Model
*/
class Group
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $code;
/**
* #var Collections\ArrayCollection
* #ORM\OneToMany(targetEntity="Application\Model\User", mappedBy="group")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $users;
/**
* Constructor
*/
public function __construct()
{
$this->users = new Collections\ArrayCollection();
}
/**
* #return mixed
*/
public function getCode()
{
return $this->code;
}
/**
* #param mixed $code
* #return Group
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
* #return Group
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return mixed
*/
public function getUsers()
{
return $this->users;
}
/**
* #param mixed $users
* #return Group
*/
public function setUsers($users)
{
$this->users = $users;
return $this;
}
}
When I try to retrieve the relation from the groups, it works great, but when I slect the users and try to get their group, Doctrine create some proxy objects and the result is an empty object with only the relationship key filled.
Can someone point me to the good direction ?
Here my code:
$query = $em->createQueryBuilder()
->select('u')
->from('Application\Model\User', 'u');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getGroup()); // proxy
###########################
$query = $em->createQueryBuilder()
->select('g')
->from('Application\Model\User\Group', 'g');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getUsers()); // ok
you don't need the $GRP_ID in the User Entity - it's already mapped with the $group relation. Doctrine handles the IDs automatically.
Also your naming-convention looks a bit weird. Normally you should use lowe-camel-case (to save you from strange errors)
Example:
$USR_CODE should be $usrCode -> to match your getter/setter: setUsrCode(), getUsrCode().
just noticed: you don't have any setters. You have to define setters for your attributes, with the naming-convention (look at my example above)
Edit:
you can map the column with the doctrine orm notation:
/**
*
* #ORM\Column(name="USR_CODE", type="string")
*/
private $usrCode;
And yes, you need setters otherwise doctrine won't be able to set the values.
You also need addUser() and removeUser() functions (since user is a Collection):
public function addUsers(Collection $users)
{
foreach($users as $user)
{
if( ! $this->users->contains($user))
{
$this->users->add($user);
$user->setGroup($this);
}
}
}
public function removeUsers(Collection $users)
{
foreach($users as $user)
{
if($this->users->contains($user)){
$this->users->remove($user);
$user->setGroup(null);
}
}
}
I'm working on a survey project and I got 3 Entities, survey(umfrage), surveyQuestion(umfrageFrage) and surveyAnswer(umfrageAntwort).
Here are the entities(removed all unnecessary fields):
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Umfrage
*
* #ORM\Table(name="umfrage")
* #ORM\Entity
*/
class Umfrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Fragen
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageFrage", mappedBy="umfrage", cascade={"persist","remove"})
*/
private $fragen;
public function __construct() {
$this->fragen = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function setFragen($fragen)
{
$this->fragen = $fragen;
return $this;
}
/** Get fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function getFragen() {
return $this->fragen;
}
public function addFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage($this);
$this->fragen->add($frage);
}
}
public function removeFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage(null);
$this->fragen->removeElement($frage);
}
}
}
The Questions:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageFrage
*
* #ORM\Table(name="umfrage_frage")
* #ORM\Entity
*/
class UmfrageFrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\Umfrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\Umfrage", inversedBy="fragen")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_id", referencedColumnName="id")
* })
*/
private $umfrage;
/**
* #var Antworten
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageAntwort", mappedBy="umfrageFrage", cascade={"all"})
*/
private $antworten;
public function __construct() {
$this->antworten = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrage
*
* #param \Umfrage\Entity\Umfrage $umfrage
*
* #return UmfrageFrage
*/
public function setUmfrage(\Umfrage\Entity\Umfrage $umfrage = null)
{
$this->umfrage = $umfrage;
return $this;
}
/**
* Get umfrage
*
* #return \Umfrage\Entity\Umfrage
*/
public function getUmfrage()
{
return $this->umfrage;
}
/**
* Set antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function setAntworten($antworten)
{
$this->antworten = $antworten;
return $this;
}
/** Get antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function getAntworten() {
return $this->antworten;
}
public function addAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$antwort->setUmfrageFrage($this);
$this->antworten->add($antwort);
}
}
public function removeAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$this->antworten->removeElement($antwort);
}
}
}
The Answers:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageAntwort
*
* #ORM\Table(name="umfrage_antwort")
* #ORM\Entity
*/
class UmfrageAntwort
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\UmfrageFrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\UmfrageFrage", inversedBy="antworten")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_frage_id", referencedColumnName="id")
* })
*/
private $umfrageFrage;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrageFrage
*
* #param \Umfrage\Entity\UmfrageFrage $umfrageFrage
*
* #return UmfrageFrage
*/
public function setUmfrageFrage($umfrageFrage)
{
$this->umfrageFrage = $umfrageFrage;
return $this;
}
/**
* Get umfrageFrage
*
* #return \Umfrage\Entity\UmfrageFrage
*/
public function getUmfrageFrage()
{
return $this->umfrageFrage;
}
}
The Controller action:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('umfrage', array('action'=>'add'));
}
$umfrage = $this->getEntityManager()->find('Umfrage\Entity\Umfrage', $id);
$form = new UmfrageForm($this->getEntityManager());
$form->setHydrator(new DoctrineEntity($this->getEntityManager(),'Umfrage\Entity\Umfrage'));
$form->bind($umfrage);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getEntityManager()->persist($umfrage);
$this->getEntityManager()->flush();
// Redirect to overview
return $this->redirect()->toRoute('umfrage');
}
}
$this->layout('layout/umfrage_backend');
return new ViewModel(array(
'id' => $id,
'form' => $form
));
}
And the view:
<?php
// module/Umfrage/view/umfrage/umfrage/edit.phtml:
use Doctrine\Common\Util\Debug;
$title = 'Umfrage bearbeiten';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url(
'umfrage',
array(
'action' => 'edit',
'id' => $this->id,
)
));
echo $this->ztbForm($form);
?>
Adding a Survey works fine, Deleting also, the Survey and its related Questions/Answers are removed from the DB. Only the Update actions doesn't work as expected. Survey and Questions are updated, but for the Answers I receive an Insert, instead of an Update, which results in duplicate entries in the DB. What's wrong with the Mapping(Code)?
Thanks in advance for your help!