How persist one to one entity unidirectionally in Symfony2 - symfony

I have a problem with two entities in Symfony2 with Doctrine:
This is the first Entity:
/**
* Pedidos
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="RestCarta\Bundle\FrontendBundle\Entity\PedidosRepository")
*/
class Pedidos
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="usuario", type="string", length=100)
*/
private $usuario;
/**
* #var string
*
* #ORM\Column(name="mesa", type="string", length=3)
*/
private $mesa;
/**
* #var integer
*
* #ORM\OneToOne(targetEntity="Articulos")
* #ORM\JoinColumn(name="articulo_id", referencedColumnName="id")
*/
private $articulo;
/**
* #var string
*
* #ORM\Column(name="precio", type="decimal")
*/
private $precio;
This is the second Entity:
/**
* Articulos
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="RestCarta\Bundle\FrontendBundle\Entity\ArticulosRepository")
*/
class Articulos
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="referencia", type="string", length=100)
*/
private $referencia;
/**
* #var string
*
* #ORM\Column(name="nombre", type="string", length=255)
*/
private $nombre;
/**
* #var string
*
* #ORM\Column(name="descripcion", type="string", length=255)
*/
private $descripcion;
/**
* #var string
*
* #ORM\Column(name="precio", type="decimal")
*/
private $precio;
/**
* #var string
*
* #ORM\Column(name="imagen", type="string", length=255)
*/
private $imagen;
/**
* #ORM\ManyToOne(targetEntity="Categorias", inversedBy="articulos")
* #ORM\JoinColumn(name="categoria_id", referencedColumnName="id")
*/
protected $categoria;
And now the problem.
How i can persist one "Pedido" with contain one "Articulo" ??
I can read all "Pedido" and the LEFT JOIN with "Articulo" work perfectly, (data inserted manually via phpMyAdmin) but when I persist more data with this code:
$em = $this->getDoctrine()->getManager();
$pedido = new Pedidos();
$pedido->setUsuario('blablabla');
$pedido->setMesa('blablabla');
$pedido->setArticulo($identi);
$pedido->setPrecio('blablabla');
$em->persist($pedido);
$em->flush();
$identi = corresponds to an id of "Articulos"
The result is:
Warning: spl_object_hash() expects parameter 1 to be object, string
given in
/Applications/MAMP/htdocs/RestCarta/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php
line 1388 500 Internal Server Error - ContextErrorException
Please, anyone can help me?
Thanks in Advance

$identi must be a entity object, not only the ID you can use
$em->getReference('YourNamespace\Articulos', $identi);

Related

Symfony3 - The association refers to the owning side field which does not exist with ManyToMany and fields table

i'm trying to make a manyToMany relationship with more attributes than the ids, so I need two OneToMany relationships and two ManytoOne relationships having three tables/entities.
I have Product entity, Client entity and ProductClient entity:
class Client
{
/**
* #var integer
*
* #ORM\Column(name="id_client", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idClient;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
*/
private $name;
/**
* #var \ProductClient
*
* #ORM\OneToMany(targetEntity="ProductClient", mappedBy="client")
*/
private $products_clients;
}
class Product
{
/**
* #var integer
*
* #ORM\Column(name="id_product", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idProduct;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
*/
private $name;
/**
* #var \ProductClient
*
* #ORM\OneToMany(targetEntity="ProductClient", mappedBy="product")
*/
private $products_clients;
}
class ProductClient
{
/**
* #ORM\Column(name="product_id", type="integer")
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Product", inversedBy="products_clients")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id_product", nullable=false)
*/
protected $product;
/**
* #ORM\Column(name="client_id", type="integer")
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Client", inversedBy="products_clients")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id_client", nullable=false)
*/
protected $client;
/**
* #var bool
*
* #ORM\Column(name="status", type="boolean")
*/
private $status;
}
That's something like this (with its getters and setters and more attributes). But symfony launches two "invalid entities errors" when I go to the Product crud:
AppBundle\Entity\Product - The association AppBundle\Entity\Product#products_clients refers to the owning side field AppBundle\Entity\ProductClient#product which is not defined as association, but as field.
AppBundle\Entity\Product - The association AppBundle\Entity\Product#products_clients refers to the owning side field AppBundle\Entity\ProductClient#product which does not exist.
And the same result if I go to the Client crud. What's wrong?
As you can see in the error message, AppBundle\Entity\ProductClient#product is not defined as association, but as field.
Just remove this #ORM\Column(name="product_id", type="integer") and this #ORM\Column(name="client_id", type="integer").
class ProductClient
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Product", inversedBy="products_clients")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id_product", nullable=false)
*/
protected $product;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Client", inversedBy="products_clients")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id_client", nullable=false)
*/
protected $client;
/**
* #var bool
*
* #ORM\Column(name="status", type="boolean")
*/
private $status;
}

Doctrine request crash with composite key

I'm facing a big problem with Doctrine when i'm requesting a table with a composite primary key referencing foreign keys.
I have a 3 entities:
Library(idLibrary,adress), Book(idBook,title,pageCount), Container(idLibrary,idBook, quantity).
Everything is generated without any errors but when i'm doing findAll() request on my Container repository my browser freezes and nothing is showed like it was stuck in a loop (there 3 rows in my Container table).
class Bibliotheque
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=60)
*/
private $name;
/**
* #ORM\Column(name="adress", type="string", length=60)
*/
private $adress;
}
class Conteneur
{
/**
* Many Containers have One library.
* #ORM\Id
* #ORM\OneToOne(targetEntity="Bibliotheque")
* #ORM\JoinColumn(name="libraryId", referencedColumnName="id")
*/
private $library;
/**
* One Container has One book.
* #ORM\Id
* #ORM\OneToOne(targetEntity="Livre")
* #ORM\JoinColumn(name="bookId", referencedColumnName="id")
*/
private $book;
/**
* #ORM\Column(name="quantity", type="integer")
*/
private $quantity;
}
class Livre
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #ORM\Column(name="pageCount", type="integer")
*/
private $pageCount;
/**
* Un livre a plusieurs auteurs
* #ORM\ManyToMany(targetEntity="Auteur")
* #ORM\JoinTable(name="books_authors",
* joinColumns={#ORM\JoinColumn(name="book_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="author_id", referencedColumnName="id")}
* )
*/
private $authors;
}
class Auteur
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=60)
*/
private $name;
/**
* #ORM\Column(name="surname", type="string", length=60)
*/
private $prenom;
/**
* #ORM\Column(name="birthDate", type="date")
*/
private $birthDate;
}
firstly, please use only French or English for class name and variable.
Add id inside class "Container" and remove annotation #ORM\id for attributes "library" and "book"
Define attribute "authors" with ArrayCollection and add method getAuthors(), addAuthor(Author $author), removeAuthor(Author $author)
And rename the tables name => "name_id" not "nameId"
look documention http://symfony.com/doc/current/doctrine.html
class Library
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=60)
*/
private $name;
/**
* #var string $address
*
* #ORM\Column(name="address", type="string", length=60)
*/
private $address;
}
class Container
{
/**
* #var integer $id
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Many Containers have One library.
*
* #ORM\OneToOne(targetEntity="Library")
* #ORM\JoinColumn(name="library_id", referencedColumnName="id")
*/
private $library;
/**
* One Container has One book.
*
* #ORM\OneToOne(targetEntity="Book")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
private $book;
/**
* #ORM\Column(name="quantity", type="integer")
*/
private $quantity;
}
class Book
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $title
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string $pageCount
*
* #ORM\Column(name="page_count", type="integer")
*/
private $pageCount;
/**
* A book have many authors
*
* #var ArrayCollection $authors
*
* #ORM\ManyToMany(targetEntity="Auteur")
* #ORM\JoinTable(name="books_authors",
* joinColumns={#ORM\JoinColumn(name="book_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="author_id", referencedColumnName="id")}
* )
*/
private $authors;
/**
* #return ArrayCollection
*/
public function getAuthors()
{
return $this->authors;
}
/**
* #param Author $author
*
* #return $this
*/
public function addAuthor(Author $author)
{
$this->authors->add($author);
return $this;
}
/**
* #param Author $author
*
* #return $this
*/
public function removeAuthor(Author $author)
{
$this->authors->removeElement($author);
return $this;
}
}
class Author
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $firstname
*
* #ORM\Column(name="firstname", type="string", length=60)
*/
private $firstname;
/**
* #var string $lastname
*
* #ORM\Column(name="lastname", type="string", length=60)
*/
private $lastname;
/**
* #var DateTime $birthDate
*
* #ORM\Column(name="birthDate", type="date")
*/
private $birthDate;
}

Symfony save date for every change status

how i can to do this: I have OrderWork entity this for order and have relation manyToMany with Status entity. All work good, but i want have date for every saved and updated order.
* Order
*
* #ORM\Table(name="order_work")
* #ORM\Entity(repositoryClass="AppBundle\Repository\OrderWorkRepository")
*/
class OrderWork
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Client", cascade={"persist"})
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
/**
* #var string
*
* #ORM\Column(name="orderNumber", type="string", length=255)
*/
private $orderNumber;
/**
* #var string
*
* #ORM\Column(name="orderCity", type="string", length=255)
*/
private $orderCity;
/**
* #var date
*
* #ORM\Column(name="date", type="string", length=255)
*/
private $date;
/**
* #var \DateTime
*
* #ORM\Column(name="orderDate", type="string", length=255, options={"default": NULL})
*/
private $orderDate;
/**
* #var \DateTime
*
* #ORM\Column(name="returnDate", type="string", length=255, nullable=true)
*/
private $returnDate;
/**
* #var string
*
* #ORM\Column(name="device", type="string", length=255)
*/
private $device;
/**
* #ORM\ManyToOne(targetEntity="SurrogatePhone", cascade={"persist"})
* #ORM\JoinColumn(name="surrogate_id", referencedColumnName="id")
*/
private $surrogatePhone;
/**
* #var int
*
* #ORM\Column(name="orderType", type="integer")
*/
public $orderType;
/**
* #ORM\ManyToMany(targetEntity="Status")
* #ORM\JoinTable(name="order_status",
* joinColumns={#ORM\JoinColumn(name="order_id", referencedColumnName="id", unique=false)},
* inverseJoinColumns={#ORM\JoinColumn(name="status_id", referencedColumnName="id", unique=false)}
* )
*/
private $status;
How better resolve this solution?
Define date in your constructor (for creating):
class OrderWork
{
//...
public function __construct()
{
$this->date = new DateTime();
}
}
And update date field when updating:
$orderWork->setDate(new DateTime());
$em->flush();

Symfony 2 entity join or doctrine query join

I was wondering if it was possible to configure a entity to automatically load data from another entity.
Ex.
/**
* accountsUsers
*
* #ORM\Table()
* #ORM\Entity
*/
class accountsUsers
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var string
*
* #ORM\Column(name="userid",type="integer")
*/
public $userid;
/**
* #var string
*
* #ORM\Column(name="roleid",type="integer")
*/
public $roleid;
/**
* #var string
* admin,adviser,etc
* #ORM\Column(name="roleType", type="string", length=255)
*/
public $roleType;
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=255)
*/
public $firstname;
/**
* #var string
*
* #ORM\Column(name="lastname", type="string", length=255)
*/
public $lastname;
/**
* #var string
*
* #ORM\Column(name="company", type="string", length=255)
*/
public $company;
/**
* #var string
*
* #ORM\Column(name="url", type="string", length=255)
*/
public $url;
/**
* #var string
*
* #ORM\Column(name="phone", type="string", length=255)
*/
public $phone;
/**
* #var string
*
* #ORM\Column(name="phone2", type="string", length=255)
*/
public $phone2;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
*/
public $address;
/**
* #var string
*
* #ORM\Column(name="address2", type="string", length=255)
*/
public $address2;
/**
* #var string
*
* #ORM\Column(name="city", type="string", length=255)
*/
public $city;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=255)
*/
public $state;
/**
* #var string
*
* #ORM\Column(name="zip", type="string", length=255)
*/
public $zip;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
public $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
public $password;
}
AND
/**
* accounts
*
* #ORM\Table()
* #ORM\Entity
*/
class accounts
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var string
*
* #ORM\Column(name="partnerid", type="string", length=100)
*/
public $partnerid;
/**
* #var \DateTime
*
* #ORM\Column(name="subscribedate", type="date")
*/
public $subscribedate;
/**
* #var string
*
* #ORM\Column(name="connectionType", type="string", length=100)
*/
public $connectionType;
/**
* #var string
*
* #ORM\Column(name="recordkeeperTpaid", type="string", length=100)
*/
public $recordkeeperTpaid;
/**
* #var string
*
* #ORM\Column(name="recordkeeperAdviceProviderCd", type="string", length=100)
*/
public $recordkeeperAdviceProviderCd;
/**
* #var string
*
* #ORM\Column(name="recordkeeperUrl", type="string", length=200)
*/
public $recordkeeperUrl;
/**
* #var string
*
* #ORM\Column(name="recordkeeperUser", type="string", length=100)
*/
public $recordkeeperUser;
/**
* #var string
*
* #ORM\Column(name="recordkeeperPass", type="string", length=100)
*/
public $recordkeeperPass;
/**
* #var string
*
* #ORM\Column(name="recordkeeperPortfoliosAvailable", type="smallint")
*/
public $recordkeeperPortfoliosAvailable;
/**
* #var string
*
* #ORM\Column(name="recordkeeperRiskBasedFundsAvailable", type="smallint")
*/
public $recordkeeperRiskBasedFundsAvailable;
/**
* #var string
*
* #ORM\Column(name="investmentsMinScore", type="integer")
*/
public $investmentsMinScore;
/**
* #var string
*
* #ORM\Column(name="investmentsMaxScore", type="integer")
*/
public $investmentsMaxScore;
/**
* #var string
*
* #ORM\Column(name="ACAon", type="smallint")
*/
public $ACAon;
/**
* #var string
*
* #ORM\Column(name="MSTClientID", type="string", length = 100)
*/
public $MSTClientID;
}
Is it possible to set up accountsUsers to automatically load in all the accounts data when accountsUsers is accessed by findby, findbyone, etc. The relationship is accountsUsers.userid = accounts.id.
If not, how would I do this in a join using doctrine. I know how to do it using pure raw sql.
Ex. SELECT * FROM accounts a LEFT JOIN accountsUsers b ON a.id =
b.userid
It is not possible to load separate entities in one query (i.e. with a JOIN) just by using annotations. You'll have to define a custom query in your repository which instructs Doctrine, via DQL or QueryBuilder, to join with the related entities.
It was a big gotcha for me as well, but using fetch="EAGER" in the annotation defining the association doesn't actually use a JOIN to retrieve the result - it just issues 2 separate queries to pre-fill the relationship so that its first access does not trigger the lazy loading process.
See also this question for more information.
Symfony developed relations which give you the ability to define a property in entity files and relate it to other entity.
There are two ways.
First way:
In your case,
first you have to make a column in users table(for example name it account) and relate it to account.id column using foreign key's, then in App\Entity\Accounts you can define a property name $users and relate it to App\Entity\Users like code below:
/**
* #ORM\OneToMany(targetEntity="App\Entity\Users", mappedBy="account")
*/
private $users;
and one in App\Entity\Users
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Accounts", inversedBy="users")
*/
private $Account;
like this whenever you get a object from App\Entity\Accounts
a key with the name users will return that have the information of all of this account users just the result:
SELECT * FROM accounts a LEFT JOIN accountsUsers b ON a.id = b.userid
will give you.
The second way is pretty easy just by using make:entity command
php bin/console make:entity
you can make a new column and make a relation for it, command will ask you about everything step by step and its pretty much so simple working with it that you don't need to read the document but if you need more information this is the link to read about it
https://symfony.com/doc/current/doctrine/associations.html#the-manytoone-onetomany-association

Doctrine - "Missing value for primary key"

I have a problem with an invalid mapping. I keep getting an error with message:
Missing value for primary key course on "Namespace\XXX\Entity\Subject"
The doctrine:schema:validate command returns the following:
[Mapping] FAIL - The entity-class 'Namespace\XXX\Entity\Subject' mapping is invalid:
* The join columns of the association 'schedule' have to match to ALL identifier columns of the target entity 'Namespace\XXX\Entity\Subject', however 'id, course, class, day, timeslot' are missing.
This is my mapping:
Subject-entity
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="message", type="string", length=255)
*/
private $message;
/**
* #ORM\ManyToOne(targetEntity="Oggi\ScheduleBundle\Entity\Schedule", inversedBy="subjects")
* #ORM\JoinColumn(name="schedule", referencedColumnName="id")
*/
private $schedule;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="datetime")
*/
private $created;
Schedule Entity
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Oggi\KlasBundle\Entity\Course")
* #ORM\JoinColumn(name="course", referencedColumnName="id")
*/
private $course;
/**
* #var string
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Oggi\KlasBundle\Entity\Klas", inversedBy="schedules")
* #ORM\JoinColumn(name="class", referencedColumnName="id")
*/
private $klas;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Day")
* #ORM\JoinColumn(name="day", referencedColumnName="id")
*/
private $day;
/**
* #var string
*
* #ORM\Id
* #ORM\OneToOne(targetEntity="Timeslot")
* #ORM\JoinColumn(name="timeslot", referencedColumnName="id")
*/
private $timeslot;
/**
* #ORM\OneToMany(targetEntity="Oggi\CalendarBundle\Entity\Subject", mappedBy="schedule")
*/
private $subjects;
I suppose that what Symfony is telling me to do is include all primary keys in my subject-entity. Is there a way to only include the ID of the schedule in this entity. I had this in mind:
Thanks in advance!
The reason you get this error is because all columns in your Schedule entity are marked as an Id.
Just remove #ORM\Id from all columns but $id - this should fix the case

Resources