I am using Doctrine 2 with ZF2.
I have a sites entity with the following primary key field.
/**
* #var string
* #ORM\Column(name="site_id", type="string", length=10, nullable=false)
* #ORM\Id
*/
private $siteId;
And the following index's
* #ORM\Table(name="sites", indexes={
* #ORM\Index(name="PRIMARY", columns={"site_id"}),
* #ORM\Index(name="country_id", columns={"country_id"}),
* #ORM\Index(name="timezone_id", columns={"timezone_id"}),
* #ORM\Index(name="vat_rate_id", columns={"vat_rate_id"}),
* #ORM\Index(name="site_mode_id", columns={"site_mode_id"}),
* #ORM\Index(name="created_by_user_id", columns={"created_by_user_id"}),
* })
When I run php ./vendor/doctrine/doctrine-module/bin/doctrine-module orm:validate-schema from the command line I get the following error message.
[Doctrine\DBAL\Schema\SchemaException]
An index with name 'primary' was already defined on table 'sites'.
However it also reports The mapping files are correct.
Does anyone know why this error is being generated?
Many thanks in advance.
EDIT
Full entity as requested
/**
* Sites Entity
*
* #author Garry Childs
*
* #ORM\Table(name="sites", indexes={
* #ORM\Index(name="country_id", columns={"country_id"}),
* #ORM\Index(name="timezone_id", columns={"timezone_id"}),
* #ORM\Index(name="vat_rate_id", columns={"vat_rate_id"}),
* #ORM\Index(name="site_mode_id", columns={"site_mode_id"}),
* #ORM\Index(name="created_by_user_id", columns={"created_by_user_id"}),
* })
* #ORM\Entity(repositoryClass="Application\Entity\Repository\SitesRepository")
* #ORM\HasLifecycleCallbacks
*/
class Sites extends AbstractEntity
{
/**
* #var string
* #ORM\Column(name="site_id", type="string", length=10, nullable=false)
* #ORM\Id
*/
private $siteId;
/**
* #var string
*
* #ORM\Column(name="domain_name", type="string", length=255, nullable=false)
*/
private $domainName;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=30, nullable=false)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="email_address", type="string", length=254, nullable=false)
*/
private $emailAddress;
/**
* #var string
*
* #ORM\Column(name="layout", type="string", length=30, nullable=true)
*/
private $layout;
/**
* #var string
*
* #ORM\Column(name="homepage", type="string", length=30, nullable=true)
*/
private $homepage;
/**
* #var string
*
* #ORM\Column(name="bookmark_icon", type="string", length=20, nullable=false)
*/
private $bookmarkIcon = 'bookmark.png';
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=200, nullable=false)
*/
private $address;
/**
* #var string
*
* #ORM\Column(name="town", type="string", length=30, nullable=false)
*/
private $town;
/**
* #var string
*
* #ORM\Column(name="county", type="string", length=30, nullable=false)
*/
private $county;
/**
* #var \Application\Entity\Countries
*
* #ORM\ManyToOne(targetEntity="Application\Entity\Countries")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_id", referencedColumnName="country_id")
* })
*/
private $country;
/**
* #var string
*
* #ORM\Column(name="post_code", type="string", length=7, nullable=false)
*/
private $postCode;
/**
* #var \Application\Entity\Timezones
*
* #ORM\ManyToOne(targetEntity="Application\Entity\Timezones")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="timezone_id", referencedColumnName="timezone_id")
* })
*/
private $timezone;
/**
* #var string
*
* #ORM\Column(name="locale", type="string", length=5, nullable=false)
*/
private $locale;
/**
* #var string
*
* #ORM\Column(name="currency_code", type="string", length=3, nullable=false)
*/
private $currencyCode;
/**
* #var string
*
* #ORM\Column(name="vat_number", type="string", length=10, nullable=true)
*/
private $vatNumber;
/**
* #var \Application\Entity\VatRates
*
* #ORM\ManyToOne(targetEntity="Application\Entity\VatRates", inversedBy="sites")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="vat_rate_id", referencedColumnName="vat_rate_id")
* })
*/
private $vatRate;
/**
* #var \DateTime
*
* #ORM\Column(name="date_created", type="datetime")
*/
private $dateCreated;
/**
* #var \DateTime
*
* #ORM\Column(name="date_modified", type="datetime")
*/
private $dateModified;
/**
* #var \Application\Entity\Users
*
* #ORM\ManyToOne(targetEntity="Application\Entity\Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="created_by_user_id", referencedColumnName="user_id")
* })
*/
private $createdBy;
/**
* #var Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Application\Entity\Categories", mappedBy="site")
*/
private $categories;
/**
* #var \Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Application\Entity\SiteCountries", cascade="persist", mappedBy="site")
*/
private $siteCountries;
/**
* #var \Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Application\Entity\SiteShippingMethods", cascade="persist", mappedBy="site")
*/
private $shippingMethods;
/**
* #var \Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Application\Entity\SitePaymentMethods", cascade="persist", mappedBy="site")
*/
private $sitePaymentMethods;
/**
* #var \Application\Entity\SiteModes
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SiteModes")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="site_mode_id", referencedColumnName="site_mode_id")
* })
*/
private $siteMode;
/**
*
* #var integer
* #ORM\Column(name="payment_days", type="integer", nullable=false)
*/
private $paymentDays;
/**
*
* #var integer
* #ORM\Column(name="products_per_page", type="integer", nullable=false)
*/
private $productsPerPage;
/**
* #var \Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Application\Entity\Invoices", mappedBy="site")
* })
*/
private $invoices;
public function __construct()
{
$this->categories = new ArrayCollection();
$this->siteCountries = new ArrayCollection();
$this->shippingMethods = new ArrayCollection();
$this->vatRate = NULL;
$this->sitePaymentMethods = new ArrayCollection();
$this->invoices = new ArrayCollection();
$this->productsPerPage = 15;
}
.... Getters & Setters
/**
* #ORM\PrePersist
* #return \Application\Entity\Users
*/
public function prePersist()
{
$this->dateCreated = $this->getCurrentDateTime();
$this->dateModified = $this->getCurrentDateTime();
$this->currencyCode = $this->strToUpper($this->currencyCode);
$this->createdBy = $this->getAuthUser();
return $this;
}
/**
* #ORM\PreUpdate
* #return \Application\Entity\Users
*/
public function preUpdate()
{
$this->dateModified = $this->getCurrentDateTime();
$this->currencyCode = $this->strToUpper($this->currencyCode);
return $this;
}
You already marked the site_id column as your primary column when you added #ORM\Id annotation to the $siteId property. It is not necessary to add the following line:
#ORM\Index(name="PRIMARY", columns={"site_id"}),
Remove that line and you will see that the site_id column will be indexed properly as PRIMARY index automatically in your database.
Read more on this in chapter 4.5. Identifiers / Primary Keys in the doctrine documentation
Related
Good afternoon,
I try to get all data with one DQL query in a specific Repository.
The problem is, even if I have Host & Page[] (collection), the query returns null values for this entities.
This is my entities ([EDIT] after question by delboy1978uk):
/**
* #ORM\Entity(repositoryClass="App\Repository\WebsiteRepository")
*/
class Website
{
/**
* #var int|null $id
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string $domainName
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $domainName;
/**
* #var string $language
*
* #ORM\Column(type="string", length=2, nullable=false)
*/
private $language;
/**
* #var Host $host
*
* #ORM\ManyToOne(targetEntity="App\Entity\Host", cascade={"persist"})
* #ORM\JoinColumn(name="host_id", referencedColumnName="id", nullable=false)
*/
private $host;
/**
* #var ArrayCollection $pages
*
* #ORM\OneToMany(targetEntity="App\Entity\Page", mappedBy="website", cascade={"persist"})
*/
private $pages;
/**
* Website constructor.
*/
public function __construct()
{
$this->pages = new ArrayCollection();
}
}
/**
* #ORM\Entity(repositoryClass="App\Repository\HostRepository")
*/
class Host
{
/**
* #var int|null $id
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string|null
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $legalName;
/**
* #var string|null
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $address;
/**
* #var string|null
*
* #ORM\Column(type="string", length=15, nullable=false)
*/
private $phoneNumber;
}
/**
* #ORM\Entity(repositoryClass="App\Repository\PageRepository")
*/
class Page
{
/**
* #var int|null $id
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string|null $title
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $title;
/**
* #var string|null $route
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $route;
/**
* #var string|null $template
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $template;
/**
* #var Website $website
*
* #ORM\ManyToOne(targetEntity="App\Entity\Website", inversedBy="pages")
*/
private $website;
}
This is my method to find configuration ([EDIT] after question by delboy1978uk):
class WebsiteRepository extends ServiceEntityRepository
{
/**
* WebsiteRepository constructor.
*
* #param ManagerRegistry $registry
*/
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Website::class);
}
public function findConfiguration(): array
{
return $this->getEntityManager()->createQuery(
'SELECT w
FROM App\Entity\Website w
JOIN w.host h
LEFT JOIN w.pages p'
)->getResult();
}
}
I expect to returns Host & Page[] (collection) from findConfiguration method in WebsiteRepository.
Thanks you for your help.
This is the solution with findConfiguration method in WebsiteRepository for findConfiguration method:
SELECT w, h, p
FROM App\Entity\Website w
LEFT JOIN w.host h
LEFT JOIN w.pages p
I made a mapping of 4 entities, but when I view the objects in the collection , all objects are populated except the last.
Here Entities
User.php
/**
* User
*
* #ORM\Table(name="`user`")
* #ORM\Entity(repositoryClass="icgo\AdminBundle\Repository\UserRepository")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255,nullable=false)
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="surname", type="string", length=255,nullable=false)
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $surname;
/**
*
* #ORM\OneToMany(targetEntity="Affectation",mappedBy="user",cascade={"persist"})
* #ORM\JoinColumn(nullable=false)
*/
private $affectations;
public function __construct()
{
parent::__construct();
$this->affectations = new \Doctrine\Common\Collections\ArrayCollection();
}
...... getters and setters ....
Affectation.php
/**
* Affectation
*
* #ORM\Table(name="affectation")
* #ORM\Entity(repositoryClass="icgo\AdminBundle\Repository\AffectationRepository")
*/
class Affectation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="User",inversedBy="affectations",cascade={"persist"})
* #ORM\JoinColumn(name="uid",referencedColumnName="id")
*/
private $user;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="icgo\WorkPlaceBundle\Entity\Workplace",inversedBy="affectations",cascade={"persist"})
* #ORM\JoinColumn(name="wid",referencedColumnName="id")
*/
private $workplace;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Role",inversedBy="affectations",cascade={"persist"})
* #ORM\JoinColumn(name="rid",referencedColumnName="rid")
*/
private $role;
.... getters and setters .....
Workplace.php
/**
* workplace
*
* #ORM\Table(name="workplace")
* #ORM\Entity(repositoryClass="icgo\WorkPlaceBundle\Repository\WorkplaceRepository")
*/
class Workplace
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="wfa", type="string", length=1, nullable=false)
*/
private $famille;
/**
* #var string
*
* #ORM\Column(name="nickname", type="string", length=255)
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $nickname;
/**
* #var \DateTime
*
* #ORM\Column(name="date_start", type="date")
* #Assert\Date()
*/
private $dateStart;
/**
* #var \DateTime
*
* #ORM\Column(name="date_end", type="date")
* #Assert\Date()
*/
private $dateEnd;
/**
* #var string
*
* #ORM\Column(name="label_short", type="string", length=255)
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $labelShort;
/**
* #var string
*
* #ORM\Column(name="label_long", type="text")
*/
private $labelLong;
/**
*
* #ORM\OneToMany(targetEntity="icgo\AdminBundle\Entity\Affectation",mappedBy="workplace")
* #ORM\JoinColumn(nullable=false)
*/
private $affectations;
.... getters and setters .....
Role.php
/**
* Role
*
* #ORM\Table(name="role")
* #ORM\Entity(repositoryClass="icgo\AdminBundle\Repository\RoleRepository")
*/
class Role
{
/**
* #var int
*
* #ORM\Column(name="rid", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="label_short", type="string", length=255)
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $labelShort;
/**
* #var string
*
* #ORM\Column(name="label_long", type="text", nullable=false)
*/
private $labelLong;
/**
*
* #ORM\OneToMany(targetEntity="Affectation",mappedBy="role")
* #ORM\JoinColumn(nullable=false)
*/
private $affectations;
.... getters and setters ......
UserRepository.php
class UserRepository extends \Doctrine\ORM\EntityRepository
{
public function getUsers(){
$query = $this->createQueryBuilder('u')
->select('u','a','r')
->addSelect('w')
->leftJoin('u.affectations','a')
->leftJoin('a.workplace','w')
->leftJoin('a.role','r')
->getQuery();
return $query->getResult();
}
}
Result dump
Dump image
As see, for the last object User , the table assignments, workplace and role objects are null. All the previous user are populated
Thanks for help
In symfony I created two entities from a database already created. I used the following commands from the console of symfony:
php app/console doctrine:mapping:import --force IDFrontendBundle xml
php app/console doctrine:mapping:convert annotation ./src
php app/console doctrine:generate:entities IDFrontendBundle
Two of the entities that generate me and where I have the problem are as follows
use Doctrine\ORM\Mapping as ORM;
/**
* ProviderRate
*
* #ORM\Table(name="provider_rate", indexes={#ORM\Index(name="fk_proveedor_has_producto_compra_producto_compra1_idx", columns={"product_id"}), #ORM\Index(name="fk_id_tarifa_proveedor_id_moneda1_idx", columns={"currency_id"}), #ORM\Index(name="IDX_3A645C45A53A8AA", columns={"provider_id"})})
* #ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProviderRateRepository")
*/
class ProviderRate
{
/**
* #var string
*
* #ORM\Column(name="reference", type="string", length=45, nullable=false)
*/
private $reference;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* #var integer
*
* #ORM\Column(name="amount_per_unit", type="integer", nullable=true)
*/
private $amountPerUnit;
/**
* #var string
*
* #ORM\Column(name="unit_price", type="decimal", precision=25, scale=3, nullable=false)
*/
private $unitPrice;
/**
* #var string
*
* #ORM\Column(name="discount", type="decimal", precision=25, scale=3, nullable=false)
*/
private $discount;
/**
* #var \IDavid\FrontendBundle\Entity\Providers
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Providers")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="provider_id", referencedColumnName="id")
* })
*/
private $provider;
/**
* #var \IDavid\FrontendBundle\Entity\Products
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Products")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* })
*/
private $product;
/**
* #var \IDavid\FrontendBundle\Entity\Currencies
*
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="currency_id", referencedColumnName="id")
* })
*/
private $currency;
and
use Doctrine\ORM\Mapping as ORM;
/**
* Products
*
* #ORM\Table(name="products", uniqueConstraints={#ORM\UniqueConstraint(name="id_producto_UNIQUE", columns={"id"})}, indexes={#ORM\Index(name="fk_id_productos_id_categorias1_idx", columns={"category_id"}), #ORM\Index(name="fk_id_productos_id_producto_tipo1_idx", columns={"type"}), #ORM\Index(name="fk_id_productos_id_moneda1_idx", columns={"currency_id"})})
* #ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProductsRepository")
*/
class Products
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=45, nullable=false)
*/
private $code;
/**
* #var string
*
* #ORM\Column(name="description_long", type="text", nullable=false)
*/
private $descriptionLong;
/**
* #var integer
*
* #ORM\Column(name="amount_per_unit", type="integer", nullable=false)
*/
private $amountPerUnit;
/**
* #var string
*
* #ORM\Column(name="weight", type="decimal", precision=11, scale=3, nullable=false)
*/
private $weight;
/**
* #var string
*
* #ORM\Column(name="web", type="string", length=100, nullable=false)
*/
private $web;
/**
* #var boolean
*
* #ORM\Column(name="isActive", type="boolean", nullable=false)
*/
private $isactive;
/**
* #var \DateTime
*
* #ORM\Column(name="createdtime", type="datetime", nullable=false)
*/
private $createdtime;
/**
* #var \DateTime
*
* #ORM\Column(name="modifiedtime", type="datetime", nullable=false)
*/
private $modifiedtime;
/**
* #var \DateTime
*
* #ORM\Column(name="deletedtime", type="datetime", nullable=true)
*/
private $deletedtime;
/**
* #var boolean
*
* #ORM\Column(name="isDeleted", type="boolean", nullable=false)
*/
private $isdeleted;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \IDavid\FrontendBundle\Entity\Categories
*
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Categories")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
* })
*/
private $category;
/**
* #var \IDavid\FrontendBundle\Entity\ProductTypes
*
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\ProductTypes")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="type", referencedColumnName="id")
* })
*/
private $type;
/**
* #var \IDavid\FrontendBundle\Entity\Currencies
*
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="currency_id", referencedColumnName="id")
* })
*/
private $currency;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Sets", inversedBy="product")
* #ORM\JoinTable(name="products_sets",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="set_id", referencedColumnName="id")
* }
* )
*/
private $set;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="productParentid")
*/
private $product;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Documents", inversedBy="product")
* #ORM\JoinTable(name="product_attachments",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="document_id", referencedColumnName="id")
* }
* )
*/
private $document;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Images", inversedBy="product")
* #ORM\JoinTable(name="products_images",
* joinColumns={
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
* }
* )
*/
private $image;
/**
* Constructor
*/
public function __construct()
{
$this->set = new \Doctrine\Common\Collections\ArrayCollection();
$this->product = new \Doctrine\Common\Collections\ArrayCollection();
$this->document = new \Doctrine\Common\Collections\ArrayCollection();
$this->image = new \Doctrine\Common\Collections\ArrayCollection();
$this->providerRate = new \Doctrine\Common\Collections\ArrayCollection();
}
I tried creating a new variable to join the two tables in reverse order into the product class
/**
* #ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="product_id")
* })
*/
private $providerRate;
But when I make a DQL query, symfony tells me that there is no association.
Is there any way to do this?
$dql = "SELECT p, pr FROM IDFrontendBundle:Products p
JOIN p.providerRate pr";
$query = $this->getEntityManager()->createQuery($dql);
You relationship cardinality is different on each side.
ProviderRate -> Product (OneToOne)
Product -> ProviderRate (OneToMany)
As such, it won't work. OneToOne should be on both sides or, OneToMany should be paired with ManyToOne.
I assume the following:
One Product can has multiple ProviderRates. It that correct?
If so, you need:
ProviderRate class
/**
* #var \IDavid\FrontendBundle\Entity\Products
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="providerRate")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* })
*/
private $product;
Products class
/**
* #ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
*/
private $providerRate;
As you can see, once you declase #JoinColums on either of relationshp's sides, there is no need to specify one on other side. Also, inversedBy should be matched by mappedBy.
Does this help?
EDIT
Change mappedBy and inversedBy attribute order.
ProviderRate class
/**
* #var \IDavid\FrontendBundle\Entity\Products
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", inversedBy="providerRate")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
* })
*/
private $product;
Products class
/**
* #ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", mappedBy="product")
*/
private $providerRate;
I'm having some issues when trying to join two tables with Doctrine 2. When I attempt to add a new item to the table I get the error:
A new entity was found through a relationship that was not configured to cascade persist operations: #. Explicitly persist the new entity or configure cascading persist operations on the relationship.
When I try to update a row in the table I'm getting the error:
The given entity has no identity.
I'm trying to join the winner entities event id to the id of an event so i can gather data on the event for the view. I'm defiantly getting an id returned for from the form for the update but it doesn't seem to let me update it.
Update:
So having played around with things a little, when I add the cascade="{persist}" option I get a class not found error, removing it and adding the full namespace results in it claiming the entity does not exist...
<?php
namespace ZC\Entity;
/**
* ZC\Entity\Winner
*
* #Table(name="winner")
* #Entity(repositoryClass="ZC\Entity\Repository\Winner")
*/
class Winner
{
/**
* #var integer $id
*
* #Column(name="id", type="integer", nullable=false, unique=false, precision=0, scale=0)
* #Id
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $copy
*
* #Column(name="copy", type="text", length="", unique=false, nullable=true, precision=0, scale=0)
*/
protected $copy;
/**
* #var string $url
*
* #Column(name="url", type="string", length="255", unique=false, nullable=true, precision=0, scale=0)
*/
protected $url;
/**
*
* #ManyToOne(targetEntity="Events")
* #JoinColumns=({
* #JoinColumn(name="event", referencedColumnName="id")
* })
*
*/
protected $event;
/**
* __get function.
*
* #access protected
* #param mixed $property
* #return void
*/
public function __get($property) {
return $this->$property;
}
/**
* __set function.
*
* #access protected
* #param mixed $property
* #param mixed $value
* #return void
*/
public function __set($property, $value) {
$this->$property = $value;
}
}
<?php
namespace ZC\Entity;
/**
* ZC\Entity\Events
*
* #Table(name="events")
* #Entity(repositoryClass="ZC\Entity\Repository\Events")
*/
class Events
{
/**
* #var integer $id
*
* #Column(name="id", type="integer", nullable=false, unique=false, precision=0, scale=0)
* #Id
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $title
*
* #Column(name="title", type="string", length="255", unique=false, nullable=false, precision=0, scale=0)
*/
protected $title;
/**
* #var string $description
*
* #Column(name="description", type="text", length="", unique=false, nullable=true, precision=0, scale=0)
*/
protected $description;
/**
* #var string $status
*
* #Column(name="status", type="smallint", length="1", unique=false, nullable=false, precision=0, scale=0)
*/
protected $status = 0;
/**
* #var string $date
*
* #Column(name="date", type="string", length="255", unique=false, nullable=false, precision=0, scale=0)
*/
protected $date;
/**
* #var string $lang
*
* #Column(name="lang", type="string", length="255", unique=false, nullable=false, precision=0, scale=0)
*/
protected $lang;
/**
* __get function.
*
* #access protected
* #param mixed $property
* #return void
*/
public function __get($property) {
return $this->$property;
}
/**
* __set function.
*
* #access protected
* #param mixed $property
* #param mixed $value
* #return void
*/
public function __set($property, $value) {
$this->$property = $value;
}
}
Use cascade={"persist"}:
/**
*
* #ManyToOne(targetEntity="Acme\Bundle\AcmeBundle\Entity\Events", cascade={"persist"})
* #JoinColumns=({
* #JoinColumn(name="event", referencedColumnName="id")
* })
*
*/
protected $event;
I have a PHPUnit test that's using a Doctrine2 custom repository and Doctrine Fixtures. I wanted to test that a query gave me back an expected entity from my fixture.
But when I try $this->assertEquals($expectedEntity, $result);, I get Fatal error: out of memory. I'm guessing it is recursing into all the relations and the entity manager and whatnot.
Is there a good way to test this equality? Should I just assertEquals on the IDs of the entities?
Edit:
Here is the test code
<?php
use Liip\FunctionalTestBundle\Test\WebTestCase;
class AbstractRepositoryTestCase extends WebTestCase
{
/**
* #var Doctrine\ORM\EntityRepository
*/
protected $repo;
/**
* #var Doctrine\Common\DataFixtures\Executor\AbstractExecutor
*/
protected $fixtureExecutor;
/**
* #var string Which repository to load, overriden by derived class
*/
protected $repoName;
/**
* #var array Fixture classes to load on setup
*/
protected $fixtures = array();
public function setUp()
{
$kernel = static::createKernel();
$this->repo = $kernel->boot();
$this->repo = $kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository($this->repoName);
$this->fixtureExecutor = $this->loadFixtures($this->getFixtures());
}
public function getFixtures()
{
return $this->fixtures;
}
}
class ArticleRepositoryTest extends AbstractRepositoryTestCase
{
/**
* #var string Which repository to load, overriden by derived class
*/
protected $repoName = 'MyMainBundle:Article';
/**
* #var array Fixture classes to load on setup
*/
protected $fixtures = array(
'My\MainBundle\DataFixtures\ORM\LoadUserData',
'My\MainBundle\DataFixtures\ORM\LoadArticleData',
'My\MainBundle\DataFixtures\ORM\LoadFeedsData',
'My\MainBundle\DataFixtures\ORM\LoadFeedDataData',
'My\MainBundle\DataFixtures\ORM\LoadUserReadArticleData',
);
public function testGetNextArticle_ExpectCorrect()
{
/** #var Doctrine\Common\DataFixtures\ReferenceRepository **/
$refRepo = $this->fixtureExecutor->getReferenceRepository();
/** #var FeedStream\MainBundle\Entity\Article **/
$curr = $refRepo->getReference('feed-1-article-3');
$expected = $refRepo->getReference('feed-1-article-2');
$expected2 = $refRepo->getReference('feed-1-article-1');
$next = $this->repo->getNextArticle($curr->getFeed()->getId(), $curr);
$this->assertNotNull($next);
// this is the part that doesn't work
$this->assertEquals($expected, $next);
// this is the code I've used instead
$this->assertEquals($expected->getId(), $next->getId());
}
}
Here is the entity (getters/setters omitted to save space)
<?php
namespace My\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* My\MainBundle\Entity\Article
*
* #ORM\Table(name="articles", uniqueConstraints={
* #ORM\UniqueConstraint(name="feed_guid", columns={"feed_id", "guid"}),
* #ORM\UniqueConstraint(name="article_slug_unique", columns={"feed_id", "slug"})
* })
* #ORM\Entity(repositoryClass="My\MainBundle\Repository\ArticleRepository")
*/
class Article
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $guid
*
* #ORM\Column(name="guid", type="string", length=255, nullable=false)
*/
private $guid;
/**
* #var string $title
*
* #ORM\Column(name="title", type="string", length=255, nullable=false)
*/
private $title;
/**
* #var datetime $pubDate
*
* #ORM\Column(name="pub_date", type="datetime", nullable=true)
*/
private $pubDate;
/**
* #var text $summary
*
* #ORM\Column(name="summary", type="text", nullable=true)
*/
private $summary;
/**
* #var text $content
*
* #ORM\Column(name="content", type="text", nullable=false)
*/
private $content;
/**
* #var string $sourceUrl
*
* #ORM\Column(name="source_url", type="string", length=255, nullable=true)
*/
private $sourceUrl;
/**
* #var string $commentUrl
*
* #ORM\Column(name="comment_url", type="string", length=255, nullable=true)
*/
private $commentUrl;
/**
* #var string $slug
*
* #ORM\Column(name="slug", type="string", length=64, nullable=false)
*/
private $slug;
/**
* #var string $thumbnailFile
*
* #ORM\Column(name="thumbnail_file", type="string", length=64, nullable=true)
*/
private $thumbnailFile;
/**
* #var My\MainBundle\Entity\ArticleEnclosure
*
* #ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleEnclosure")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="thumbnail_enclosure_id", referencedColumnName="id")
* })
*/
private $thumbnailEnclosure;
/**
* #var My\MainBundle\Entity\ArticleImageScrape
*
* #ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleImageScrape")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="thumbnail_scrape_id", referencedColumnName="id", unique=false)
* })
*/
private $thumbnailScrape;
/**
* #var My\MainBundle\Entity\ArticleBitly
*
* #ORM\OneToOne(targetEntity="My\MainBundle\Entity\ArticleBitly", mappedBy="article", orphanRemoval=true)
*/
private $bitly;
/**
* #var My\MainBundle\Entity\ArticleEnclosure
*
* #ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleEnclosure", mappedBy="article", orphanRemoval=true)
*/
private $enclosures;
/**
* #var My\MainBundle\Entity\ArticleImageScrape
*
* #ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleImageScrape", mappedBy="article", orphanRemoval=true)
*/
private $scrapes;
/**
* #var My\MainBundle\Entity\ArticleLink
*
* #ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleLink", mappedBy="article", orphanRemoval=true)
*/
private $links;
/**
* #var My\MainBundle\Entity\Feed
*
* #ORM\ManyToOne(targetEntity="My\MainBundle\Entity\Feed", inversedBy="articles")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="feed_id", referencedColumnName="id", nullable=false)
* })
*/
private $feed;
/**
* #var My\MainBundle\Entity\ArticleAuthor
*
* #ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleAuthor", inversedBy="articles")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
* })
*/
private $author;
public function __construct()
{
$this->links = new \Doctrine\Common\Collections\ArrayCollection();
}
}
You should also test the class in addition to the ID.