doctrine2 constraint violation - php

I have the following entity with this rekation:
/**
* Acme\DemoBundle\Entity\Book
*
* #ORM\Table(name="book")
* #ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\BookRepository")
* #ORM\HasLifecycleCallbacks
* #UniqueEntity(fields="publickey", groups={"publickey"})
*/
class P1guestlistentry {
/**
* #var P1guestlistentrystatistic
*
* #ORM\OneToOne(targetEntity="P1guestlistentrystatistic", orphanRemoval=true, cascade={"all"}, fetch="EAGER")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="fkstatistic", referencedColumnName="pkId", nullable=false)
* })
*/
private $fkstatistic;
When I try to remove an object like here:
$this->getEntityManager()->getConnection()->beginTransaction();
try{
$book = $this->getEntityManager()->getRepository('AchmeDemoBundle:Book')->find(3928);
$this->getEntityManager()->remove($book);
$this->getEntityManager()->flush();
$this->getEntityManager()->getConnection()->commit();
}catch(Exception $e){
$this->getEntityManager()->getConnection()->rollBack();
echo $e->getMessage();
}
exit;
I can do whatever I want, I get the following error:
An exception occurred while executing 'DELETE FROM book WHERE pkId = ?' with params {"1":3928}: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (p1.book, CONSTRAINT FK_F51A442F78734022 FOREIGN KEY (fkstatistic) REFERENCES bookstatistic (pkId))
Has anbybody an idea what I'm doing wrong?
I tried a lot of methods but nothing helps.

In case someone runs into a similar issue, here is the solution:
/**
* #var statistic
*
* #ORM\OneToOne(targetEntity="statistic", cascade="ALL")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="fkStatistic", referencedColumnName="pkId", onDelete="SET NULL")
* })
*/
The onDelete option will remove the relation first and then doctrine will do the cascade operation.

Related

Doctrine behavior with cascade={"remove"} on a OneToMany relation with a ManyToOne to same entity

i have two entities : Post and Comments where a Post can have one or more comments.
I implemented a cascade={"remove"} on the Post's comments OneToMany which works greats !
All comments related to a Posts gets deleted after Post suppression.
Then, i decided to add a topComment attribute in my Post Entity (Many topComment to One Post). After that, i tried to delete a Post with related Comments but the suppression fails because of the foreign key constraint even if the post have no topComment...
Here is the error i get :
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`lab_test_cascade_remove`.`comment`, CONSTRAINT `FK_9474526C4B89032C` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`))
I got rid of this error by adding a #JoinColumn(nullable=true) annotation to the Post's topComment attribute but i find that strange because this is the default behavior of doctrine if #JoinColumn annotation isn't set...
Could someone can please explain me what happens internally and cause this error even if the Post don't have any topComment ?
Many thanks in advance.
Here are my entities (attributes only) :
Post :
/**
* #ORM\Entity(repositoryClass="App\Repository\PostRepository")
*/
class Post
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="post", cascade={"remove"})
*/
private $comments;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Comment")
*/
private $topComment;
Comment :
/**
* #ORM\Entity(repositoryClass="App\Repository\CommentRepository")
*/
class Comment
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Post", inversedBy="comments")
* #ORM\JoinColumn(nullable=false)
*/
private $post;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;

Foreign key and cascade problems on delete Symfony4/Doctrine

I want to delete a property with my user but I have the following error :
An exception occurred while executing 'DELETE FROM property WHERE id = ?' with params [1]:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (gestImmo.equipment, CONSTRAINT FK_D338D583517FE9FE FOREIGN KEY (equipment_id) REFERENCES property (id))
I googled it and (I think) it's a cascade problem. So I searched on forums but I didn't solved the problem. I asked for help to an experimented coworker but we didn't fix the mistake ... Hope you could help me.
In my User entity there is :
/**
* #ORM\OneToMany(targetEntity="App\Entity\Property", mappedBy="userProperty")
*/
private $properties;
In my property Entity there is :
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="properties")
* #JoinColumn(name="id", referencedColumnName="id", onDelete="CASCADE")
*/
private $userProperty;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Equipment", mappedBy="equipment")
* #JoinColumn(name="id", referencedColumnName="equipement_id", onDelete="CASCADE")
*/
private $equipments;
and in my equipments entity there is :
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Property", inversedBy="equipments")
* #Assert\Type("string")
* #var string
*/
private $equipment;
Thanks for your help !
Setting the onDelete="CASCADE" in your manyToOne annotation should be enough.
Don't forget to bin/console make:migration after that. Everything you change in your ORM must be migrated in order to apply the changes into the database.
You cannot delete property because it is referenced in column equipment_id in table equipment. This foreign key constraint means that equipment.equipment_id must point to a valid(existing) id of property - property.id.
If you want to delete property, then before that you either:
Delete equipment records where equipment_id = {id of property you want to delete}
Or change those equipment_id to null
EDIT
Looks like your annotations are incorrect. If I understood your relations correctly, then it should be something like this.
Property entity:
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="properties")
* #JoinColumn(name="user_property_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $userProperty;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Equipment", mappedBy="equipment")
*/
private $equipments;
Equipment entity:
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Property", inversedBy="equipments")
* #ORM\JoinColumn(name="equipment_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $equipment;

Weird issue with related entity in Doctrine

I'm using Doctrine2 inside Symfony and I have the following setup:
An Item class:
/**
* Class Item
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="OneShortly\CommonBundle\Entity\ItemRepository")
*/
class Item
{
/**
* #ORM\ManyToOne(targetEntity="Category")
* #ORM\JoinColumn(name="primaryCategory", referencedColumnName="foreignId")
*/
private $primaryCategory;
}
And a Category class:
/**
* Category
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="OneShortly\CommonBundle\Entity\CategoryRepository")
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="foreignId", type="integer", unique=true)
*/
private $foreignId;
}
Now when I do this:
$item = new Item();
$item->setPrimaryCategory($category);
$this->em->persist($item);
$this->em->flush();
I get this error:
[Symfony\Component\Debug\Exception\ContextErrorException] Notice:
Undefined index: foreignId in
home/www/project/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
line 692
Now, I've been looking at this from all angles and still cannot see what is wrong with this code. Can you help?
After some more digging I figured out myself by using doctrine:schema:validate:
[Mapping] FAIL - The entity-class
'Acme\CommonBundle\Entity\Item' mapping is invalid:
* The referenced column name 'foreignId' has to be a primary key column on the target entity class
'Acme\CommonBundle\Entity\Category'.
[Database] FAIL - The database schema is not in sync with the current
mapping file.
So, I changed the foreign key from foreignId to id (which happens to be the primary key) and it works. I could, of course, just use foreignId as a primary key, but I realized actually I don't need that.
Take a look at http://symfony.com/doc/current/book/doctrine.html#relationship-mapping-metadata.
You should rather have:
/**
* Class Item
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="OneShortly\CommonBundle\Entity\ItemRepository")
*/
class Item
{
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="items")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $primaryCategory;
}
and:
/**
* Category
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="OneShortly\CommonBundle\Entity\CategoryRepository")
*/
class Category
{
/**
* #ORM\OneToMany(targetEntity="Item", mappedBy="primaryCategory")
*/
private $items;
}
Forget ID in ORM.

How to add a field/parameter on primary key?

I work with Symfony2.0 and Doctrine, and I created this entity:
class MetaInformationsQuestionUser
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Myproject\Bundle\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Myproject\Bundle\QuestionsBundle\Entity\MetaInformationsQuestion")
*/
private $metainformationsquestion;
/**
* #var datetime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var datetime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated;
/**
* #var array $score
*
* #ORM\Column(name="score", type="array", nullable="true")
*/
private $score;
So this entity is a link for a many-to-many relation with attributes. (in this case, the score and creation and update dates).
My idea is to add a record of every question that each user plays, with the score he gets.
My problem is that I get this error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-3' for key 'PRIMARY'
So my question is: How can I add for example the create date to the primary key, or just remove the fact to have a primary key on this?
Ok I got it,
I needed to add:
* #ORM\Id
In my created field:
/**
* #var datetime $created
*
* #ORM\Id
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
It made what I wanted!
Here are the documentation:
https://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-id

Doctrine 2.1 reference table

I have a reference table album_content which has: album_id, content_id, and sort_key. I set it up as an entity with #ManyToOne relations:
/**
* #ManyToOne(targetEntity="Album")
* #JoinColumns({
* #JoinColumn(name="album_id", referencedColumnName="id")
* })
*/
private $albumId;
/**
* #ManyToOne(targetEntity="Content")
* #JoinColumns({
* #JoinColumn(name="content_id", referencedColumnName="id")
* })
*/
private $contentId;
/**
* #Column(name="sort_key", type="integer", nullable=false)
*/
private $sortKey;
Right now Doctrine is complaining No identifier/primary key specified. What's the correct annotation to reference these without adding an extra ID column?
First, you probably shouldn't be naming things $contentId or $albumId, but instead just call them $content and $album.
That said, the quick solution is to add #Id annotations to both of your associations.
The manual goes into further detail about using composite keys in Doctrine 2.

Categories