Doctrine 2 not creating foreign key - doctrine-orm

I have this piece of code inside an Entity:
/**
* #ORM\ManyToOne(targetEntity="Centers")
* #ORM\JoinColumn(name="center_id", referencedColumnName="id")
* #ORM\Column(type="string", length=36, name="center_id")
*/
protected $centerId;
However, schema:update says that all is in sync. Even changing Centers to some other inexistent word, produces no error.

Please delete the last line of annotation doctrine like this and change $centerId by $center (there is object an object) :
/**
* #ORM\ManyToOne(targetEntity="Centers")
* #ORM\JoinColumn(name="center_id", referencedColumnName="id")
*/
protected $center;
Clear cache and run your command.
Tell me if this solved your problem.

Related

Persisting Doctrine Entity with Collection results in exception

Am working on a simple setup with two tables with a one to many (and inversed) relationship. The two corresponding entities are:
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ArticlesRepository::class)
* #ORM\Table(name="articles")
*/
class Article
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="unique_id", type="integer")
*/
protected int $idx;
/**
* The inverse side
* #ORM\OneToMany(targetEntity="Comment", mappedBy="article")
* #ORM\Column(name="uid", type="integer", nullable=true)
*/
protected $id;
public function __construct()
{
$this->id=new ArrayCollection();
}
}
and
use Doctrine\ORM\Mapping as ORM;
/**
* ORM\Entity(repositoryClass="CommentRepository::class")
* ORM\Table(name="comments")
*/
class Comment
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="uid", type="integer")
*/
protected $idx;
/**
* The owning side
* #ORM\ManyToOne(targetEntity="Article", inversedBy="uid")
* #ORM\JoinColumn(name="article", referencedColumnName="uid")
*/
protected $article;
protected $content;
}
Attempting to persist a new blank Article
$article=new Article();
$em->persist($article);
$em->flush();
results in the following exception
An exception occurred while executing 'INSERT INTO articles (uid) VALUES (?)' with params [{}]: PHP Warning: Object of class Doctrine\Common\Collections\ArrayCollection could not be converted to float in ...\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\Mysqli\MysqliStatement.php line 164
I went searching for answers and came across suggestions close to but don't touch on this subject. One had to do with removing the type indication of the column. So I did and it gets stuck with the following exception
An exception occurred while executing 'INSERT INTO articles (uid) VALUES (?)' with params [{}]: Cannot add or update a child row: a foreign key constraint fails...
When type is removed, the field defaults to type string which makes no difference, since Doctrine still attempts to store an empty array in an integer field (see the values in the exception above).
Question: How can I get the setup to work properly and persist all objects correctly?
It turns out that the #ORM\OneToMany annotation in the Article entity should be used on a non-existent database field. In other words, property $id should not be an actual field in the database table of the entity.

The database schema is not in sync with the current mapping file (but it is !)

I just fixed some things in my code. I'm now trying to validate my schema
php bin/console doctrine:schema:validate
Doctrine tells me my mapping is correct but my database schema is not. So I'm doing a
schema:update --dump-sql
which results in the same ALTER again and again, that I already performed many times.
Here is the ALTER :
ALTER TABLE migration_versions CHANGE version version VARCHAR(14) NOT NULL;
I did it (with --force), the entity is reflecting the change already :
**
* MigrationVersions
*
* #ORM\Table(name="migration_versions")
* #ORM\Entity
*/
class MigrationVersions
{
/**
* #var string
*
* #ORM\Column(name="version", type="string", length=14, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $version;
I am correct right ? its varchar, lenght 14...
And so is it in my database
I don't think Im making a mistake here but I may be missing something.
Have you already verified that the server_version in the doctrine config file is correct? (config/packages/doctrine.yaml in symfony5)
It happened to me that I was using MariaDB (version 10.4.11-MariaDB - Source distribution) and in the file doctrine.yaml the server_version parameter had the value 5.7.
After I corrected that, the error no longer occurred.
Also you can check this question

Delete operations in doctrine 2

For eg I have entities like User,Item, Image. User has many items. Item has many images.
Which delete option should I choose, cascade={'remove'} or onDelete=Cascade ?
Also I have life cycle callbacks on Image. I know the difference between above mentioned cascade options. I was wondering if I used onDelete=cascade option, on deleting a User object, will the life cycle callback like PostRemove() be called ?
Here are my entities:
//User.php
class User {
/**
* #ORM\OneToMany(targetEntity="Item", mappedBy="user", onDelete="CASCADE")
*/
private $items;
}
//Item.php
class Item {
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User", inversedBy="items")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $user;
/**
* #ORM\OneToMany(targetEntity="ItemImage", mappedBy="item",onDelete="CASCADE")
*/
protected $images;
}
//ItemImage.php
class ItemImage {
/* Setters and getter **/
/**
* #var Items
*
* #ORM\ManyToOne(targetEntity="Item", inversedBy="images")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="item_id", referencedColumnName="id")
* })
*/
private $item;
/**
* #ORM\PostRemove()
*/
public function removeUpload() {
unlink($this->getUploadDir() . '/' . $this->imageName);
}
}
My question is when a user is deleted, will all the items associated with user and images related to the items be deleted ? I also want the PostRemove() callback of Image entity be called when User is deleted ? Which option should I use, onDelete="cascade" or cascade={'remove'} for such cases?
onDelete='CASCADE' will add an SQL level ON DELETE CASCADE. So yes, the images will be deleted from the table. This is very efficient because the database handles the deletes.
To have the listener called cascade={'remove'} is necessary. This makes Doctrine fetch the object's graph, which is slower.
Both options may be specified at the same time. In this case Doctrine will act as described in the last paragraph, but DELETEs not coming from Doctrine will cascade correctly, too; no listeners will be called in this case obviously.
I would tend to specify cascade={'remove'} only in this case to avoid accidental DELETEs without the listener being called (if there is no cleanup task for unreferenced files).
Details can be found in the Doctrine documentation.

doctrine2 Detach doesn't work when there is association to put order in session

I'm trying to detach an object from entity_manager in doctrine2 in order to put him in session but it doesn't work. not when there is Association.
Ex:
<?php
namespace Travelyo\CoreBundle\Entity\Order;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="bundles")
* /
class Bundle
{
/**
* #var integer $id
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Order", inversedBy="orders",cascade={"detach","merge","remove"})
* #ORM\JoinColumn(name="order_id", referencedColumnName="id")
*/
private $order;
 }
There is no other relation in order.
But when I'm trying to do that
$em = $this->getDoctrine()->getEntityManager();
$bundle = $em->getRepository('TravelyoCoreBundle:Order\Bundle')->find(27);
$em->detach($bundle);
$em->detach($bundle->order);
serialize($bundle);
It's not working, I have all the object dependecies, proxies,...
If I'm doing that before detach
$bundle->setOrder(new Order());
Then the serialize is perfect, I just have the bundle.
What am I missing here ?
Even if your object is detached, it still has references to the doctrine components used to create it.
As a simple advice, I can tell you to simply serialize the object identifier instead. That's much cleaner, and while it will require you to perform a query on the other side (the unserialize part), you will avoid a lot of problems.
Just don't serialize your entities, it's just messy.

Doctrine 2.0 vs 2.1 cascade remove OneToMany

Hello I have problem when trying to cascade remove entities in OneToMany relations.
After a few hours of debugging I tried to downgrade the doctrine from the latest 2.1.2 to 2.0.2 and It suddenly starts working.
Imagin two entities Company and Address in relation 1:N.
/**
* #Entity
*/
class Company extends Entity
{
/**
* #var integer
* #id #Column(type="integer")
* #generatedValue
*/
private $id;
/**
* #var Collection
* #OneToMany(targetEntity="Address",mappedBy="company", cascade={"persist","remove"})
*/
private $addresses;
}
/**
* #Entity
*/
class Address extends Entity
{
/**
* #var integer
* #id #Column(type="integer")
* #generatedValue
*/
private $id;
/**
* #var Company
* #ManyToOne(targetEntity="Company", inversedBy="addresses")
* #JoinColumn(name="company_id", referencedColumnName="id",nullable=false)
*/
private $company;
}
when I try to remove the entity Company, I would like the assigned addresses will be removed as well.
$em->remove($company);
$em->flush();
In doctrine 2.1.2 the deletion of addresses is not performed so the integrity constraint fails. In version 2.0.2 there it works perfectly. Wierd thing on it is, if I use EntityAudit extension https://github.com/simplethings/EntityAudit the LogRevisionListener is corretly versioning the addresses entities (set them revtype = DEL) in doctrine 2.1.2 (of course in 2.0.2 as well) but the UnitOfWork is not removing it.
Is there any difference how to handle cascade removing in 2.0.2 and in 2.1.2?
Thank you very much
Try using this on the addresses attribute of your Company Class
#OneToMany(targetEntity="Address",mappedBy="company",
cascade={"persist"}, orphanRemoval=true)
I had the same problem... Relations were added or updated, but not deleted, even if I had cascade: [persist, remove].
I found out that I didn't need the "remove" attribute in "cascade", but I had to add the orphanRemoval: true.
I was going crazy, you made my day!
I have met the same problem and i have solved him with that code :
$em->remove($object);
$em->flush();
$em->remove($user);
$em->flush();
Maybe you can use a findAll on your company for the addresses and remove this with a foreach like that :
// Return all the addresses of the company
$addresses = $em->getRepository(...)->findAllAddressesByCompany($company);
$em->remove($company);
foreach ($address in $addresses)
{
$em->remove($address);
}
That's not a very good method but for now, that's all I've found.