Not valid Doctrine2 mapping: The entity-class 'Downloads' mapping is invalid - symfony

I am trying to define a OneToMany bidirectional (to avoid a ManyToMany and extra table) and I am doing (I think) as docs says here but certainly I am missing something since I am getting this error after run the doctrine:schema:validate command:
The association PlatformBundle\Entity\Downloads#identifier refers to the owning side field PlatformBundle\Entity\Identifier#downloads which does not exist.
This is how the entities looks like (just the relevant fields):
class Identifier
{
/*
* #var Downloads
* #ORM\ManyToOne(targetEntity="Downloads", inversedBy="identifier")
* #ORM\JoinColumn(name="downloads_id", referencedColumnName="id")
*/
protected $downloads;
}
class Downloads
{
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Identifier", mappedBy="downloads")
*/
protected $identifier;
public function __construct() {
$this->identifier = new ArrayCollection();
}
}
This is a association where a download is assigned to many identifier. What I am doing wrong or missing here?

You are mising an * in Identifier Class :
/**<- this one could cost you many hours :P
* #var Downloads
* #ORM\ManyToOne(targetEntity="Downloads", inversedBy="identifier")
* #ORM\JoinColumn(name="downloads_id", referencedColumnName="id")
*/
protected $downloads;

Related

Symfony 6.1 Doctrine gives error 'Could not resolve type of column "id" of class "App\Entity\Officecurrencymax"'

I am getting the error Could not resolve type of column "id" of class "App\Entity\Officecurrencymax" from my installation. Have checked similar questions but I can't seem to get the Doctrine annotations right.
I have 2 entities with a ManyToOne relationship, Office and OfficeCurrencyMax. One Office can have many OfficeCurrencyMax's.
/**
* Office
*
* #ORM\Table(name="Office")
* #ORM\Entity(repositoryClass="App\Repository\OfficeRepository")
*/
class Office
{
// ...
/**
* #ORM\ManyToOne(targetEntity="Officecurrencymax", inversedBy="offices")
*/
private $officeCurrencyMaxes;
// ...
public function getOfficeCurrencyMaxes(): ?Officecurrencymax
{
return $this->officeCurrencyMaxes;
}
public function setOfficeCurrencyMaxes(?Officecurrencymax $officeCurrencyMaxes): self
{
$this->officeCurrencyMaxes = $officeCurrencyMaxes;
return $this;
}
}
Then there is the Officecurrencymax entity:
/**
* Officecurrencymax
*
* #ORM\Table(name="OfficeCurrencyMax", indexes={#ORM\Index(name="IDX_6F39111B73FD6E34", columns={"Office"})})
* #ORM\Entity(repositoryClass="App\Repository\OfficeCurrencyMaxRepository")
*/
class Officecurrencymax
{
// ...
/**
* #var integer
*
* #ORM\Column(name="Id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Office
*
* #ORM\ManyToOne(targetEntity="Office", inversedBy="offices")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Office", referencedColumnName="OfficeId")
* })
*/
private $office;
// ...
public function getId(): ?int
{
return $this->id;
}
// ...
}
I had to cut down the code a lot since StackOverflow wouldn't let me post since it looks like your post is mainly code, please add some more details.
In your case, you want to have 1-Office have Many-Officecurrencymax
So Office should have a OneToMany property and Officecurrencymax a ManyToOne.
There are a few errors, for example your Office entity says that the property is inversed by: inversedBy="offices" whereas $offices does not exist in the Officecurrencymax entity.
Your OneToMany in Office should look like:
/**
* #ORM\OneToMany(targetEntity=Officecurrencymax, mappedBy="office")
*/
private $officeCurrencyMaxes;
And in Officecurrencymax we have the opposite side of the relation:
/**
* #ORM\ManyToOne(targetEntity=Office, inversedBy="officeCurrencyMaxes")
* #ORM\JoinColumn(name="Office", referencedColumnName="OfficeId")
*/
private $office;
Do not forget to update the database schema.
based on these docs I would assume the default column name for your mapping should be id (note the case). You have capitalized your column name for some reason
#ORM\Column(name="Id" ...
I would suggest simply changing that to
#ORM\Column(name="id" ...

Symfony entity no configured for cascade

Can anyone help me explaining what I am doing wrong? I try to set an entity in relation to an file. Its about Supplier and Stock.
My Stock entity looks like
/**
* #ORM\ManyToOne(targetEntity="PrClientBundle\Entity\Lieferanten")
* #ORM\JoinColumn(name="liefer_id", referencedColumnName="id")
* #var lieferant
*/
private $lieferant;
I also using getter and setter like following
/**
* Set lieferant
*
* #param \PrClientBundle\Entity\Lieferanten $lieferant
* #return Leadbase
*/
public function setLieferant(\PrClientBundle\Entity\Lieferanten $lieferant = null)
{
$this->lieferant = $lieferant;
return $this;
}
/**
* Get lieferant
*
* #return \PrClientBundle\Entity\Lieferanten
*/
public function getLieferant()
{
return $this->lieferant;
}
When I import new Stockitems like:
$lead->setLieferant($lieferant);
I get the following errormessage which I really don't understand :(
[Doctrine\ORM\ORMInvalidArgumentException]
A new entity was found through the relationship 'PrLeadBundle\Entity\Leadbase#lieferant' that was not configured to cascade persist operations for entity: PrClientBundle\Enti
ty\Lieferanten#000000002a45dae80000000002f826ff. 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 'PrClientBundle\Entity\Lieferante
n#__toString()' to get a clue.
It would be very great if you could help me understanding what am I doing wrong.

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;
/.../
}

ManyToMany relationship with extra fields in symfony2 orm doctrine

Hi i have that same question as here: Many-to-many self relation with extra fields? but i cant find an answer :/ I tried first ManyToOne and at the other site OneToMany ... but then i could not use something like
public function hasFriend(User $user)
{
return $this->myFriends->contains($user);
}
because there was some this problem:
This function is called, taking a User type $user variable and you then use the contains() function on $this->myFriends.
$this->myFriends is an ArrayCollection of Requests (so different type than User) and from the doctrine documentation about contains():
The comparison of two elements is strict, that means not only the value but also the type must match.
So what is the best way to solve this ManyToMany relationship with extra fields? Or if i would go back and set the onetomany and manytoone relationship how can i modify the hasFriend method? To example check if ID is in array collection of ID's.
EDIT: i have this table... and what i need is:
1. select my friends... and my followers ...check if i am friend with him or not. (because he can be friend with me and i dont have to be with him... like on twitter). I could make manytomany but i need extra fields like: "viewed" "time when he subscribe me" as you can see at my table.
And make query like this and then be able in twig check if (app.user.hasFriend(follower) or something like that)
$qb = $this->createQueryBuilder('r')
->select('u')
->innerJoin('UserBundle:User', 'u')
->Where('r.friend_id=:id')
->setParameter('id', $id)
->orderBy('r.time', 'DESC')
->setMaxResults(50);
return $qb->getQuery()
->getResult();
I was trying to have a many to many relationship with extra fields, and couldn't make it work either... The thing I read in a forum (can't remember where) was:
If you add data to a relationship, then it's not a relationship anymore. It's a new entity.
And it's the right thing to do. Create a new entity with the new fields, and if you need it, create a custom repository to add the methods you need.
A <--- Many to many with field ---> B
would become
A --One to many--> C (with new fields) <-- One to many--B
and of course, C has ManyToOne relationships with both A and B.
I searched everywhere on how to do this, but in the end, it's the right thing to do, if you add data, it's no longer a relationship.
You can also copy what contains usually do, or try to overwrite it in a custom repository, to do whatever you need it to do.
I hope this helps.
I'm adding another answer since it has nothing to do with my original answer. Using the new info you posted, I'm calling the table/entity you posted "Follower". The original entity, "User".
What happens if you create the following associations:
namespace Acme\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\UserBundle\Entity\User
*
* #ORM\Table()
* #ORM\Entity
*/
class User
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="Acme\FollowerBundle\Entity\Follower", mappedBy="followeduser")
*/
protected $followers;
/**
* #ORM\OneToMany(targetEntity="Acme\FollowerBundle\Entity\Follower", mappedBy="followeeuser")
*/
protected $followees;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function __construct()
{
$this->followers = new \Doctrine\Common\Collections\ArrayCollection();
$this->followees = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add followers
*
* #param Acme\FollowerBundle\Entity\Follower $follower
*/
public function addFollower(\Acme\FollowerBundle\Entity\Follower $follower)
{
$this->followers[] = $follower;
}
/**
* Add followees
*
* #param Acme\FollowerBundle\Entity\Follower $followee
*/
public function addFollowee(\Acme\FollowerBundle\Entity\Follower $followee)
{
$this->followees[] = $followee;
}
/**
* Get followers
*
* #return Doctrine\Common\Collections\Collection
*/
public function getFollowers()
{
return $this->followers;
}
/**
* Get followees
*
* #return Doctrine\Common\Collections\Collection
*/
public function getFollowees()
{
return $this->followees;
}
}
namespace Acme\FollowerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\FollowerBundle\Entity\Follower
*
* #ORM\Table()
* #ORM\Entity
*/
class Follower
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="followers")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $followeduser;
/**
* #ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="followees")
* #ORM\JoinColumn(name="followee_id", referencedColumnName="id")
*/
protected $followeeuser;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set followeduser
*
* #param Acme\UserBundle\Entity\User $followeduser
*/
public function setFolloweduser(\Acme\UserBundle\Entity\User $followeduser)
{
$this->followeduser = $followeduser;
}
/**
* Get followeduser
*
* #return Acme\UserBundle\Entity\User
*/
public function getFolloweduser()
{
return $this->followeduser;
}
/**
* Set followeeuser
*
* #param Acme\UserBundle\Entity\User $followeeuser
*/
public function setFolloweeuser(\Acme\UserBundle\Entity\User $followeeuser)
{
$this->followeeuser = $followeeuser;
}
/**
* Get followeeuser
*
* #return Acme\UserBundle\Entity\User
*/
public function getFolloweeuser()
{
return $this->followeeuser;
}
}
I'm not sure if this would do the trick, I really don't have much time to test it, but if it doesn't, I thnk that it's on it's way. I'm using two relations, because you don't need a many to many. You need to reference that a user can have a lot of followers, and a follower can follow a lot of users, but since the "user" table is the same one, I did two relations, they have nothing to do with eachother, they just reference the same entity but for different things.
Try that and experiment what happens. You should be able to do things like:
$user->getFollowers();
$follower->getFollowedUser();
and you could then check if a user is being followed by a follower whose user_id equals $userThatIwantToCheck
and you could search in Followers for a Follower whose user = $user and followeduser=$possibleFriend

Symfony2 app/console not generating properties or schema updates for Entity Relationships/Associations

I am reading and following along in code what is written in the Symfony2 book on using Database and Doctrine (http://symfony.com/doc/2.0/book/doctrine.html). I have reached the "Entity Relationships/Associations" section but the framework does not seem to be doing what it is meant to be doing. I have added the protected $category field to the Product entity and added the $products field to the Category entity. My Product and Category entities are as below:
Product:
<?php
namespace mydomain\mywebsiteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Product
*
* #ORM\Table()
* #ORM\Entity
*/
class Product
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/*
* #ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
/**
* Set description
*
* #param string $description
* #return Product
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Category:
<?php
namespace mydomain\mywebsiteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use \Doctrine\Common\Collections\ArrayCollection;
/**
* Category
*
* #ORM\Table()
* #ORM\Entity
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/*
* #ORM\OneToMany(targetEntity="Product", mappedBy="category")
*/
protected $products;
public function __construct(){
$this->products = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
* #return Category
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
According to the documentation, if i now execute
$ php app/console doctrine:generate:entities mydomain
the framework should generate the getters/setters for the new category field in Product and for the new products field in Category.
HOWEVER when i run the command it supposedly updates the entities but it does not add the properties. I have compared with the backup(~) files and there are no differences. If i add another field (e.g. description2) and add doctrine annotations for persistence to it then it generates the properties. I ignored this at first and manually added the properties for the mapping fields and then executed:
$php app/console doctrine:schema:update --force
for it to add the new association columns.
HOWEVER once again it told me that the metadata and schema were upto date.
I have deleted the app/cache/dev folder and allowed the system to recreate it but it has made no difference.
Can anyone see why the framework is not behaving as described in the documentation??
Thanks
You have forgotten one star here:
/*
* #ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
it must be
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
UPDATE: After trying different things with absolutely no success i ended up deleting the entire bundle and associated database and starting from scratch again. Second time around things are generated correctly and the database schema is being updated correctly. Such flaky behavior is EXTREMELY POOR of the framework and as mentioned in the comment above is the reason that as a developer i am moving away from Grails. Now i find that symfony2 has the same sort of problems.
When i use a framework i should not need to always keep in the back of my mind whether something is not working because the framework is buggy. This is quite unacceptable for such a mainstream framework and it would seem i am not the only person that has come across such kind of problems. The framework developers should definitely address such issues either by (preferably) resolving them or providing some means of understanding why the framework fails on random occasions.
Based on what I found the issue is that you can't have two types of definitions..in the book the entity create comand for category also creates a yml configoration so the annotations failed. You must use either annotations or yml or xml or php. Once I removed the yml config and recreated the tables with annotations it worked..be careful and don't use the comnad for the category createion..you will still though get an error that the description is mandatory field :)
I had the exact same issue and I solved it like this:
Delete the "doctrine"-Folder containing the yml-files with the (in your case redundant!) configuration for the entities. Do this ONLY on your test-system for educational purposes.
Some background-information (maybe someone with more experience than me - probably almost everybody here ;o)) can add to this:
Doctrine preferes YML-Schema configuration over annotations in the entity-class (/** #ORM ... */)
when working through the book you might have created a blog-entity with YML-Schema configuration a few chapters in before chapter 8 - maybe you played around a little and this YML-Schema is in the same bundle than your chapter 8 exercise
consequently: Doctrine thinks you want to use YML but it finds only configuation for "anotherEntity" but not for product and category
OR: you run a few Doctrine commands for testing and choose once (by mistake?) YML and voilĂ : all further annotation chances will be ignored because i.e. a product.orm.yml exists
Hope that helped. I just started chapter 10 ;-)
When it comes to generating getters and setters Symfony is just using the ReflectionClass to look if the methods already exist.
It doesn't look what properties are written in the annotation.
Concerning the schema update problem I don't have another solution then resetting the database and creating it from scratch.
I faced this problems a few times but never really found a good solution, it seems Symfony doesn't differ between some properties, which results in not finding any updates.
I don't have a framework by hand now, to look it up. Maybe you can try to find out what schema:update does exactly thus finding the error.

Resources