Symfony, ManyToMany refers to the owning side field which does not exist - symfony

I have a #ManyToMany relation with two entities.
I have (short code)
class Photo
{
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", mappedBy="photos")
*/
protected $users;
}
class User
{
/**
* #ORM\ManyToMany(targetEntity="MyBundle\PhotoBundle\Entity\Photo", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_photos")
*/
protected $photos;
}
php app/console doctrine:schema:validate
-> [Mapping] FAIL - The entity-class 'MyBundle\PhotoBundle\Entity\Photo' mapping is invalid:
* The association MyBundle\PhotoBundle\Entity\Photo#users refers to the owning side field Application\Sonata\UserBundle\Entity\User#photos which does not exist.
I looked in stack and i try somethings but i still have the problem.

Try this
class Photo
{
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", mappedBy="photo")
*/
protected $users;
}
class User
{
/**
* #ORM\ManyToMany(targetEntity="MyBundle\PhotoBundle\Entity\Photo", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_photos")
*/
protected $photos;
}

Related

Doctrine doesn't update/generate fields of ManyToOne and OneToMany

I have a superclass that currently works fine (all relations and properties are updating to the database)
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\JoinColumn;
use JMS\Serializer\Annotation as JMS;
/**
* Document
*
* #Table(name="document")
* #Entity(repositoryClass="AcmeBundleDocumentRepository")
*/
class Document
{
/**
* #var string
*
* #Column(name="id", type="string")
* #Id
* #GeneratedValue(strategy="UUID")
*/
protected $id;
/**
* #var string
* #Column(name="name", type="string", length=255)
*/
protected $name;
/**
* #var string
* #Column(name="type", type="string", length=255)
*/
protected $type;
/**
* #var boolean
* #Column(name="has_attachments", type="boolean")
*/
protected $hasAttachments;
/**
* #ManyToOne(targetEntity="Delivery")
* #JoinColumn(name="delivery_id", referencedColumnName="id", nullable=false)
* #JMS\Exclude()
*/
protected $delivery;
/**
* #OneToMany(targetEntity="Extension", mappedBy="document", cascade={"persist","remove"})
**/
protected $extensions;
public function __construct()
{
$this->extensions = new ArrayCollection();
}
/* getter and setters */
}
Now I've created a entity called Note that extends to Document entity
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Entity;
/**
* Note
*
* #Table(name="note")
* #Entity(repositoryClass="NoteRepository")
*/
class Note extends Document
{
}
I am suppose that the table/entity note should generate the same things of the class that extends. But not do it
I run php bin/console doctrine:schema:update -f
this only generates properties and not FK (foreing Keys), in this case #ManyToOne and #OneToMany.
Additionally maybe help us, i have those entities on the same database
I am doing something wrong ?
As per docs I think you're missing the #MappedSuperclass annotation or you're using Doctrine inheritance in the wrong way. Be aware that a MappedSupperClass is not an entity by itself instead is just a class for share common methods and properties among it is children classes (same inheritance concept that you should already know).
/**
* #MappedSuperclass
*/
class DocumentSuperClass
{
...
}
/**
* #Table(name="document")
* #Entity(repositoryClass="AcmeBundleDocumentRepository")
*/
class Document extends DocumentSuperClass
{
...
}
/**
* #Table(name="note")
* #Entity(repositoryClass="NoteRepository")
*/
class Note extends DocumentSuperClass
{
...
}

Symfony2 how to remove #asset/notblank constraint when heriting from entity

i have the following problem :
I extend an entity tableA in a tableB entity and i want to override the #assert/notblank annotation on a field.
Class tableA{
...
/**
* #ORM\Column(type="string", length=4)
* #Assert\NotBlank(message="please.enter.a.value")
*/
protected $myfield;
}
The extended class :
Class tableB extends tableA{
...
/**
* #ORM\Column(type="string", length=4, nullable=true)
*/
protected $myfield;
}
The not blank constraints of TableA is still active when i make a form using tableB.
Any idea ?
I have tried with #ORM\AttributeOverride annotation but it dont works...
It seems indeed Symfony Validation component fails to understand what's going on.
A way around isto put the Validation constraint on the getter:
Class tableA{
/**
* #ORM\Column(type="string", length=4)
*/
protected $myfield;
}
/**
* #Assert\NotBlank(message="please.enter.a.value")
*/
public function getMyfield()
{
// ...
}
And in the extended class:
Class tableAB extends tableA{
public function getMyfield()
{
// ...
}

Error mapping doctrine on OneToOne bidirectional relation

I'm trying to create an entity that is connected with another entity 1:1. The whole point is that Equip has to have an Estadi, and just one. I can update the schema correctly, the database is okay, but on the webpage debugger appears a mapping error.
The association AppBundle\Entity\Equip#estadi refers to the inverse
side field AppBundle\Entity\Estadi#nom which is not defined as
association.
The association AppBundle\Entity\Equip#estadi refers to the inverse
side field AppBundle\Entity\Estadi#nom which does not exist
This is entity Estadi:
/**
* #ORM\Entity
* #ORM\Table(name="estadis")
*/
class Estadi{
/**
* #ORM\Column(type="string",length=30)
* #ORM\OneToOne(targetEntity="Equip",mappedBy="estadi",cascade={"persist"})
* #ORM\Id
*/
protected $nom;
/**
* #ORM\Column(type="integer")
*/
protected $aforament;
/**
* #ORM\Column(type="integer")
*/
protected $num_portes;
/**
* #ORM\Column(type="string",length=50)
*/
protected $direccio;
/**
* #ORM\Column(type="string", length=4)
*/
protected $any_construccio;
/**
* #ORM\Column(type="string", length=30)
*/
protected $nom_aficio;
}
This is Entity Equip:
/**
* #ORM\Entity
* #ORM\Table(name="equips")
*/
class Equip{
/**
* #ORM\Column(type="string",length=30)
* #ORM\Id
*/
protected $nom;
/**
* #ORM\Column(type="integer")
*/
protected $punts_lliga;
/**
* #ORM\Column(type="integer")
*/
protected $num_jugadors;
/**
* #ORM\OneToOne(targetEntity="Estadi",inversedBy="nom")
* #ORM\JoinColumn(name="nom_estadi",referencedColumnName="nom",onDelete="SET NULL")
*/
protected $estadi;
/**
* #ORM\OneToOne(targetEntity="Entrenador",inversedBy="nom")
* #ORM\JoinColumn(name="nom_entrenador",referencedColumnName="nom",onDelete="SET NULL")
*/
protected $entrenador;
/**
* #ORM\ManyToOne(targetEntity="Lliga",inversedBy="equips")
* #ORM\JoinColumn(name="nom_lliga",referencedColumnName="nom",onDelete="SET NULL")
*/
protected $lliga;
/**
* #ORM\OneToMany(targetEntity="Jugador",mappedBy="nom_equip")
*/
protected $jugadors;
public function __construct(){
$this->jugadors = new ArrayCollection();
}
}
When you define the #OneToOne annotation, it should not be on your primary key. Either the owning entity should contain a single association (unidirectional), or each entity should contain an association to the other - as entities, not connected to a primary key.
Your Equip mapping should instead look like this:
/**
* #ORM\OneToOne(targetEntity="Estadi", inversedBy="equip")
* #ORM\JoinColumn(name="nom_estadi", referencedColumnName="nom")
*/
protected $estadi;
public function setEstadi(Estadi $estadi)
{
$this->estadi = $estadi;
return $this;
}
public function getEstadi()
{
return $this->estadi;
}
Your Estadi mapping should instead look like this:
/**
* #OneToOne(targetEntity="Equip", mappedBy="estadi")
*/
protected $equip;
public function getEquip(Equip $equip)
{
return $this->equip;
}
I removed the cascade and onDelete, because if you're handling everything through Doctrine it should handle that for you automatically, but you still might have a use for them. I also only put the setter on the owning entity from the way you described, but you could put it back on your Estadi entity as well - that's up to you.

Symfony2 OneToMany relationship - remove action isn't called

I'm using Symfony 2.4.6 and I'm trying to use OneToMany relationship to manage images added to a banner.
I did read a lot about the deletion of a child element (setting orphanRemoval, adding 'remove' to cascade) but none of those worked for me. What I've noticed is that remove actions isn't called at all on update.
I have 2 classes, Banner and BannerFile and using collection field type for adding images and it seems to work OK except the delete action.
class Banner
{
/.../
/**
* #ORM\OneToMany(targetEntity="BannerFile", cascade={"persist", "remove"}, mappedBy="banner", orphanRemoval=true)
*/
private $bannerFiles;
/.../
/**
* Remove bannerFiles
*
* #param BannerFile $bannerFiles
*/
public function removeBannerFile(BannerFile $bannerFiles)
{
$this->bannerFiles->removeElement($bannerFiles);
}
}
class BannerFile
{
/.../
/**
* #var integer $banner
*
* #ORM\ManyToOne(fetch="EXTRA_LAZY", inversedBy="bannerFiles", targetEntity="Banner")
* #ORM\JoinColumn(name="banner_id", nullable=false, onDelete="CASCADE", referencedColumnName="id")
*/
private $banner;
/.../
}
My problem is that the removeBannerFile isn't called.
Thanks for any help.
This happens if you use a database table engine type that does not support foreign keys (such as MyISAM).
Change your engine type to InnoDB, then run the following code to update your database schema.
php console doctrine:schema:update
Add cascade to the ManyToOne definition:
class BannerFile
{
/.../
/**
* #var integer $banner
*
* #ORM\ManyToOne(fetch="EXTRA_LAZY", inversedBy="bannerFiles", targetEntity="Banner", cascade={"remove"})
* #ORM\JoinColumn(name="banner_id", nullable=false, onDelete="CASCADE", referencedColumnName="id")
*/
private $banner;
/.../
}

how to have a one to many relationship entity deleted

I have 2 entity in my Symfony2 class:
class InstagramShopPicture
{
/**
* #Exclude()
* #ORM\OneToMany(targetEntity="InstagramPictureTag", mappedBy="picture", cascade={"remove"})
*/
protected $tags;
}
and
class InstagramPictureTag
{
/**
* #ORM\ManyToOne(targetEntity="InstagramShopPicture", inversedBy="tags")
* #ORM\JoinColumn(name="picture_id", referencedColumnName="id", nullable=false)
*/
private $picture;
}
I wanted to make sure such that when I delete InstagramShopPicture the InstagramPictureTag also gets deleted. The issue now is that whenever I try to do that with the current setup, it always complaint about some foreign key issues. What am I doing wrong here?
You need to define how to handle this deletion. Check Docs
In your case :
class InstagramShopPicture
{
/**
* #Exclude()
* #ORM\OneToMany(targetEntity="InstagramPictureTag", mappedBy="picture", orphanRemoval=true)
*/
protected $tags;
}
You can rely on Database level to handle it for you, by using onDelete
class InstagramShopPicture
{
/**
* #Exclude()
* #ORM\OneToMany(targetEntity="InstagramPictureTag", mappedBy="picture", onDelete="CASCADE")
*/
protected $tags;
}

Resources