Many-to-Many, Doctrine's Entity Generator and Pluralization - symfony

Doctrine's many-to-many logic is confusing me a bit. I have a pretty simple many-to-many relationship of recipes to categories. My base entity classes are equally simple.
The Recipe entity class...
class Recipe
{
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="categories")
* #ORM\JoinTable(name="recipe_category")
**/
private $categories;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
public function __construct() {
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
}
And the Category entity class...
class Category
{
/**
* #ORM\ManyToMany(targetEntity="Recipe")
**/
private $recipes;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
public function __construct() {
$this->recipes = new \Doctrine\Common\Collections\ArrayCollection();
}
}
Seems pretty strait forward and matches Doctrine (and Symfony2's) documentation examples. The strange behavior comes when I try and generate the getters and setters for these classes via the Symfony console app.
The relationship setters/getters are incorrect. Take, for instance, the Category setter in the Recipe class that's generated...
/**
* Add categories
*
* #param \Namespace\CookbookBundle\Entity\Category $categories
* #return Recipe
*/
public function addCategorie(\Namespace\CookbookBundle\Entity\Category $categories)
{
$this->categories[] = $categories;
return $this;
}
It looks like the auto-generation of the method name is off. It should be "addCategory" and should be passed a "category."
While I can just correct this manually, if I re-run the entity generator, it will just add them again.
Am I doing this incorrectly or is this just a quirk of the entity generator? Can I specify an over-ride via annotation?

You're not doing anything wrong as that's how symfony generates them. I usually don't use the app/console to generate them as currently they're not doing a good job. One example is as you've mentioned the pluralization of words as you've mentioned. Another obvious one is the fact that it's using the [] notation which is pretty much treating an ArrayCollection object as a PHP array. You should never treat ArrayCollections as arrays.
This is how I have implemented it myself:
public function addCategory(Category $category)
{
if (!$this->categories->contains($category)
$this->categories->add($category);
return $this;
}
Which doesn't add duplicates to the Array collection if it's already added. Same thing goes with remove:
public function removeCategory(Category $category)
{
if ($this->categories->contains($category)
$this->categories->remove($category);
}
What I've run into many times is let's say you have 4 categories and you add and remove them
$r = new Recipe();
$c1 = new Category();
$c2 = new Category();
$r->addCategory($c1);
$r->addCategory($c2);
// at this point $r->getCategories()->toArray()[0] contains $c1
// and $r->getCategories()->toArray()[1] contains $c2
$r->removeCategory($c1);
// now $r->getCategories()->toArray()[0] is empty and
// $r->getCategories()->toArray()[1] contains $c2 still
// so in order to get the first category you need to:
$r->getCategories()->first();

You are not doing anything wrong. It is just that Doctrine automatically tries to singularize the names of method stubs whenever there is a plural name for a collection property. This is the function that Doctrine calls when you run the command doctrine:generate:entities:
$methodName = Inflector::singularize($methodName);
In your case, Doctrine tries to 'singularize' the word categories but fails to recognize the singular form correctly, so it just removes an 's' from the end returning categorie.
Also, as you see, Doctrine does not singularize the parameter passed to the method stubs, leaving $categories instead of being consistent and modifying it to $categorie.
If you want to avoid this, either you do not use plural words for collections, or use plural words and change the methods afterwards. As #keyboardSmasher comments to your post, doctrine won't overwrite methods you already have when using the command doctrine:generate:entities, and wrong methods won't hurt much if left there alone.
A final note: using ArrayCollections as arrays is perfectly fine, so this code is correct:
$this->categories[] = $category;
ArrayCollection object implements Collection, which in turn implements ArrayAccess. It is done this way precisely to be able to use ArrayCollections as Arrays.

Related

Symfony 3.4 entity extra columns in controller response

I have this entity:
<?php
//namespace
//use ...
class Guide
{
private $id;
//private ...
//getters
//setters
}
?>
In a controller I use the entity manager to retrieve the data of this entity.
$guides= $em->getRepository('AppBundle:Guide')
->findAll();
My entity has 4 parameters: id, name, pages, author.
Is there any way to add two extra parameters, that aren´t in the class declaration and I don´t want in the database, if the entity manager returns for example 3 rows, I want o add two extra values to each row and return the data, for example add two boolean values: ok => true, warning => false.
I have tried this:
foreach($guides as $guide){
$guide->ok=true;
$guide->warning=false;
}
If I dump $guides, I see the two parameters like this:
-id:1
-name:'Guide 1'
-pages:12
-author:'John'
+"ok":true
+"warning":false
But when I use this to send a response:
return new Response($serializer->serialize($guides, 'json'));
The two extra parameters aren´t in the response.
You could add a property to entity and do not tag it as a ORM\Column eg:
<?php
//...
/**
* #ORM\Entity
* #ORM\Table(name="guides")
*/
class Guide
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #ORM\Column(name="title", type="string")
*/
private $name;
public $myAdditionalProperty;
//...
And then set it in your controller:
foreach($guides as $guide){
$guide->myAdditionalProperty = "my amazing value";
}
Then you can serialize your data without having additional column in your table

Cascade remove working fined but not when more than one entry... why?

I am building an app where USERS can give a SCORE to some ANSWERS left by the community.
here the schema/relations of the entities:
ANSWER (one to many with) SCORE (many to one with) USER
I want that when i remove an ANSWER, the SCORES related to that ANSWER are also deleted...
BUT when I have more than one SCORE, then symfony triggers this exception:
"SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`symfony`.`Score`, CONSTRAINT `FK_6F8F552A4AB7A507` FOREIGN KEY (`answer_id`) REFERENCES `Answer` (`id`))
I must say that it works fine if there is only one SCORE related to that answer. (strange?)
Here my entities:
you will see that I do have the cascade={"remove"}, I emphasis the fact that SCORE id is build on ANSWER_ID and USER_ID. (because I want that a SCORE can only be delivered once for an answer by a user).
class=Answer
{
/**
* #ORM\OneToMany(targetEntity="XX\BlogBundle\Entity\Score", mappedBy="answer", cascade={"persist", "remove"})
**/
private $scores;
/**
* #param \XX\BlogBundle\Entity\Score $scores
*/
public function removeScore(\XX\BlogBundle\Entity\Score $score)
{
$this->scores->removeElement($score);
}
// OTHER ATTRIBUTES ETC
}
.
class=Score
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="XX\BlogBundle\Entity\Anwer", inversedBy="scores")
*/
private $answer;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="XX\BlogBundle\Entity\User", cascade={"persist"})
*/
private $user;
/**
* #var smallint
* #ORM\Column(name="valeur", type="smallint", length=10, nullable=true)
*/
private $value;
// SETTER AND GETTER
}
.
class User
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=10)
*/
private $name;
}
I would remove them manually instead of any cascade operations.. Something like this:
public function removeAnswerAction($id)
{
...
$answer = /* ... */ ->find($id);
foreach ($answer->getScores as $score) {
$answer->removeScore($score);
$score->setAnswer(null); // it requires setAnswer(Answer $answer = null), if you used a type hint in getter
$em->remove($score); // you can remove it if you want..
}
$em->remove($answer);
$em->flush();
...
}
I don't know how cascade=remove works with collections (I've never been interested in using cascade operations), but in your case doctrine is saying that it cant remove parent (Answer object) without deleting all its collection (related Score objects)..
Probleme solved (see below my exlanation) but not sure if it is the best way. (If anyone has a better solution?)
Actually the probleme doesn't come from the entities or the cascade remove (all that part is ok, maybe it can be optimised)
The issue come from the fact that I used an $answer object on which I had removed some of its scores (throught removeScore(score) in the controller before doing $em->remove($answer).
Also when symfony/doctrine tried to remove in cascade the scores associated to that $answer it couldn't find all of them and potentially would have create some orphin entries in the database, which triggered that exception.
So because I trully need to remove some scores from the $answer object, my solution is to store all thoses scores that I remove in an array so that I can add them to the $answer object before removing it.
$answer = $em->getRepository('XXBlogBundle:Answer')->find(1);
foreach($answer->getScores() as $score)
{
// I REMOVE SOME SCORES HERE FROM THE ANSWER OBJECT
if($score->getValue() == 0)
{
$array_temp_save_score[] = $score;
$answer->removeScore($score);
}
}
// SOME OF MY CODE WHERE I USE $ANSWER WITHOUT ALL SCORE
// ...
// END OF THAT PART
foreach($array_temp_save_score as $v)
{
$answer->addScore($v);
}
$em->remove($answer);
$em->flush();

Symfony2 doctrine ManyToMany relation

I'm a beginner on Synfony2 and doctrine usage. I've created two entities as following :
For EndUser Entity (extension of FOSUserBundle ):
/**
* EndUser
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Core\CustomerBundle\Entity\EndUserRepository")
*/
class EndUser extends BaseUser {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="Core\GeneralBundle\Entity\Discipline", mappedBy="endusers")
*/
private $discipline;
and for discipline entity
class Discipline {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="Core\CustomerBundle\Entity\EndUser", inversedBy="discipline")
*/
private $endusers;
When I did "php app/console doctrine:schema:update -- force,
EndUser, Discipline and discipline_enduser tables have been created.
When I run a standard SQL request through phpmyadmin as :
select t0.*
from
discipline t0,
discipline_enduser t2
where
t2.enduser_id = 1
and
t2.discipline_id = t0.id
I obtain the expected result as the list of discipline for a specific user.
My concern is how to implement the same using the Entity with Symfony2 & Doctrine
First I would recommend to use more natural language names for you relationships, like disciplines and endUsers since it is a manyToMany bond. Also, you need to create the get and set method for each. After you have prepared all your properties for an entity you should run the command to Generate your getters and setters
//this will generate all entities
php app/console doctrine:generate:entities BundleNamespace
After that, you can do things like :
$endUser->getDisciplines(); //return all disciplines of this user
$endUser->addDiscipline($someDiscipline); //add another discipline
$endUser->removeDiscipline($iAmABadDiscipline); //remove this discipline from this user
array $disciplines = [ ... ];
$endUser->setDisciplines($disciplines); // set multiple disciplines
Same logic applies to Discipline entity, ofcourse you should update them with an EntityManager for which you can read more in the answer here.
All you really need to do is amend your EndUser entity to include the following:
use Doctrine\Common\Collections\ArrayCollection;
class EndUser extends BaseUser
{
private $discipline;
public function __construct()
{
$this->discipline = new ArrayCollection();
}
public function setDiscipline($discipline)
{
$this->discipline = $discipline;
return $this;
}
public function getDiscipline()
{
return $this->discipline;
}
}
Then similarly amend Discipline, substituting endUser for discipline.
There is no need to create the intermediate entity. Doctrine has already figured it out. Neat, huh?!
To make things more coherent, rename your class member to $disciplines (it's many-to-many, so there may be multiple disciplines in it). Then you need setters and getters in your entity to access the disciplines.
One way is to do this on the command line:
php app/console doctrine:generate:entities YourBundle:EndUser
This will add the required methods to your class. The unmodified version of the class file is backed up in EndUser.php~ in case anything is overwritten.
After doing this, you can just call the getter to obtain the disciplines:
$disciplines = $anEndUser->getDisciplines();
For example in a controller method:
public function someAction()
{
$anEndUser = $this
->getDoctrine()
->getManager()
->getRepository('YourBundle:EndUser')
->find(1)
;
$disciplines = $anEndUser->getDisciplines();
}

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