How to fix cascade dont work in inheritance - doctrine-orm

The persist method dont work in inheritance class,although I have set the property cascade in annotation (cascade="all").
/**
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="tipo", type="string")
* #ORM\DiscriminatorMap({"menu" = "Menu", "enquete" = "Enquete"})
*/
abstract class Widget{
/**
* #ORM\Id
*/
protected $id;
}
/**
* #ORM\Entity
*/
class Enquete extends Widget{
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Admin\Model\Alternativa", mappedBy="enquete", cascade="all")
*/
protected $alternativas;
}
/**
* #ORM\Entity
*/
class Alternativa{
/**
* #ORM\ManyToOne(targetEntity="Admin\Model\Enquete", inversedBy="alternativas")
* #ORM\joinColumn(name="Enquete_id", referencedColumnName="id")
*/
protected $enquete;
}
I Use persist in cascade but dont work:
$enquete->addAlternativa(New Alternativa());
$entityManager->persist($enquete);
$entityManager->flush();
The result is the follow error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Enquete_id' cannot be null

Related

Doctrine 2 Composite Primary Keys as Foreign Key

I have ClassA mapped to the entity ClassB with ManyToOne relation (simple so far).
class ClassA{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyA", type="string", length=255)
*/
private $keyA;
/**
* #var ClassB $classB
* #ORM\ManyToOne(targetEntity="ClassB", inversedBy="classAs")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ClassB_keyB", referencedColumnName="keyB")
* })
*/
private $classB;
}
And this is the ClassB:
class ClassB{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyB", type="string", length=255)
*/
private $keyB;
/**
*
* #var ClassC $classC
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ClassC", inversedBy="classBs")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ClassC_keyC", referencedColumnName="keyC")
* })
*/
private $classC;
/**
* #var ArrayCollection $classAs
* #ORM\OneToMany(targetEntity="ClassA", mappedBy="classB")
*/
private $classAs;
}
As you can notice the ClassB contains a composite primary key (2 entities and on column).
And this is the ClassC:
class ClassC{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyC", type="string", length=255)
*/
private $keyC;
/**
* #var ArrayCollection $classBs
* #ORM\OneToMany(targetEntity="ClassB", mappedBy="classC")
*/
private $classBs;
}
Whene i try to display all entities of ClassA (using findAll()) I get this exception Missing value for primary key classC on ERP\................\ClassB
What am I missing here ?!
you have to create your own method at ClassARepository and add your join columns

Create an entity that will be used by many other entities (Doctrine 2)

How can I do this?
My Entities:
Product entity
/**
* #ORM\Entity
* #ORM\Table(name="products")
*/
class Product
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $name;
/**
* (??)
* #var ArrayCollection
*/
private $images;
}
Article entity
/**
* #ORM\Entity
* #ORM\Table(name="articles")
*/
class Article
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $title;
/**
* (??)
* #var ArrayCollection
*/
private $images;
}
Image entity
/**
* #ORM\Entity
* #ORM\Table(name="images")
*/
class Image
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $name;
/**
* #ORM\Column(type="string", length=1024)
* #var string
*/
private $path;
}
I don't know how to create a link tables with additional fields like the picture. Which association should I use? How to manage these relations in entities?
Usually when you need a many to many approach Doctrine let you define such behaviour with a simple annotation.
#ORM\ManyToMany(targetEntity="full_qualified_namespace")
#ORM\JoinTable(
name="game_schemas_players",
joinColumns={#ORM\JoinColumn(name="this_field_name", referencedColumnName="id")},
inverseJoinColumns={#ORM\JoinColumn(name="that_field_anem", referencedColumnName="id")}
)
This will instruct Doctrine to create a relation the current entity and the target entity.
But that's not your case. For what I can see from your model you need to add some field on the 'middle' entity.
Here what you may want to do:
class Product
{
[...]
/**
* #var ArrayCollection | ProductImage[]
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="product")
*/
private $productImages;
}
class Image
{
[...]
/**
* #var ArrayCollection | ProductImage[]
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="image")
*/
private $productImages;
}
as you can see as defined here either Product and Image have a oneToMany relation with a middle entity which will be named ProductImage**.
The last step will be to implement such entity:
class ProductImage
{
[...]
/**
* #var Image
*
* #ORM\ManyToOne(targetEntity="Image", mappedBy="image")
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
*/
private $image;
/**
* #var Product
*
* #ORM\ManyToOne(targetEntity="Product", mappedBy="product")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
/**
* #ORM\Column(type="string", length=1024)
* #var string
*/
private $position;
}
The owning side of the relation both for Product and Image is still ProductImage.
As a side note in your entity is common practice to implement an add method in this fashion:
public function __contructor(){
$this->productImages = new ArrayCollection();
}
/**
* Add ProductImage
*
* #param ProductImage $productImage
* #return $this
*/
public function addDocument(ProductImage $productImage)
{
$productImage->addProductImage($productImage);
$this->documents->add($document);
return $this;
}
and then you can use such method with the following approach:
$product = new Product();
$image = new Image();
$productImage = new ProductImage($product,$image);
$product->addProductImage($productImage);
Don't forget to provide the usual setter method as Doctrine need them to initialize the entity.
Hope it helps, Regards.

Doctrine Single Table Inheritance and bidirectional OneToMany: columns not being generated

The data model:
The entities:
Pet:
/**
* #ORM\Entity
* #ORM\Table(name="pet")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="pet_type", type="string")
*/
abstract class Pet
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\OneToMany(
* targetEntity="Collar",
* mappedBy="pet",
* cascade={"persist", "remove"},
* orphanRemoval=TRUE
* )
* #ORM\JoinColumn(name="collars", referencedColumnName="id")
*/
protected $collars;
/**
* #ORM\Column(type="integer")
*/
protected $age;
}
Cat:
/**
* #ORM\Entity
* #ORM\Table(name="cat")
*/
class Cat extends Pet
{
/**
* #ORM\Column(type="decimal")
*/
private $purringDecibels;
}
Collar:
/**
* #ORM\Entity
* #ORM\Table(name="collar")
*/
class Collar
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Pet", inversedBy="collars")
* #ORM\JoinColumn(name="pet", referencedColumnName="id", nullable=false)
*/
private $pet;
/**
* #ORM\Column(type="string", length="255")
*/
private $color;
}
The problem:
The generated tables are fine except pet: It lacks the collars column, therefore the bidirectionality is broken. While the pet ids do get stored on the collar table, I cannot fetch collars from a pet (i.e. $pet->getCollars()) as it always returns an empty collection.
What am I missing out here?
PS:
The validate console helper says all (mapping & db) is OK.
Yes, I have my getters and setters (i.e. adders and removers)
I know about the infamous performance impact of the combination between a CTI and this kind of relationship.
You do not need to have a "collars" column on the pet table. It is a one-to-many relationship, so the only table that need to "know" about pets are the collar table.
A bidirectional relationship does not mean you need two columns on two tables.
Your map seems correct.

Doctrine 2 Association Mapping (ManyToOne and OneToMany)

I am new with Doctrine2 and need some help.
I have 2 Entities: LocationEntity and RatingEntity
RatingEntity
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* Rating
*
* #ORM\Entity
* #ORM\Table(name="`RATING`")
*/
class RatingEntity {
/**
*
* #var int
* #ORM\Id
* #ORM\Column(name="`ID`", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="RATING_ID_SEQ", initialValue=1, allocationSize=1)
*/
protected $id;
/**
*
* #var int
* #ORM\Column(name="`LOCATION_ID`", type="integer")
*/
protected $locationId;
/**
* #var LocationEntity
* #ORM\ManyToOne(targetEntity="LocationEntity", inversedBy="ratings")
* #ORM\JoinColumn(name="`LOCATION_ID`", referencedColumnName="`ID`")
*/
protected $location;
/**
* #return the $location
*/
public function getLocation() {
return $this->location;
}
/**
* #param field_type $location
*/
public function setLocation($location) {
$this->location = $location;
}
and LocationEntity
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Location
*
* #ORM\Entity
* #ORM\Table(name="`LOCATION`")
*/
class LocationEntity {
/**
*
* #var int
* #ORM\Id
* #ORM\Column(name="`ID`", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="LOCATION_ID_SEQ", initialValue=1, allocationSize=1)
*/
protected $id;
/**
*
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="RatingEntity", mappedBy="location", cascade={"persist"}, fetch="LAZY")
*/
protected $ratings;
/**
* #return the $ratings
*/
public function getRatings() {
return $this->ratings;
}
/**
* #param \Doctrine\Common\Collections\ArrayCollection $ratings
*/
public function setRatings($ratings) {
$this->ratings = $ratings;
}
/**
* Never forget to initialize all your collections!
*/
public function __construct() {
$this->ratings = new ArrayCollection();
}
If I get locations, i get ratings for location as Array,
but if I want to get Rating and Location for it, I get NULL only in getLocation().
Can somebody help?
I don't think that you need the locationId property in your Rating entity as the column is already mapped using the location property. Try removing the locationId section and see if it doesn't work as expected.

Doctrine: RuntimeException - Not all identifier properties can be found in the ResultSetMapping

I started using Doctrine and ran into trouble immediately. I have an entity defined as follows:
namespace AdminModule;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="admin_user")
*/
class User extends \Nette\Object
{
/**
* #ORM\Id
* #ORM\Column(type="string", name="guid")
* #var string
*/
protected $id;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $username;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $password;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $email;
/**
* #ORM\Column(type="datetime")
* #var datetime
*/
protected $registered;
/**
* #ORM\Column(type="datetime")
* #var datetime
*/
protected $last_login;
}
If I call
$u = $this->em->getRepository('AdminModule\User')->createQueryBuilder()
->select('u.username, u.id')
->from('AdminModule\User', 'u');
I get the RuntimeException stating that identifier property "id" is missing. However, when I run the above code with getQuery() and execute() it, it returns the result I want.
Can you help me out? If more information is needed, just tell me. Thank you.