I have a table with some fields and the first is my primary key, called token.
I need that token isn't automatically, so, I want to set this value. For example,
$em = $this->getDoctrine()->getManager();
$object->setToken("first");
$object->setValue("123");
$em->persist($object);
$em->flush();
But, in my DB, always token is null, why?
When I do flush, token value disappear.
In my entity, token is declared:
/**
* #var string
*
* #ORM\Column(name="token", type="string", length=45, nullable=false)
* #ORM\Id
*/
private $token;
/**
* Set token
*
* #param string $token
* #return Downloads
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* Get token
*
* #return string
*/
public function getToken()
{
return $this->token;
}
Try with ORM\GeneratedValue
/**
* #var string
*
* #ORM\Column(name="token", type="string", length=45, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $token;
Maybe this could help Doctrine2 Primary Key.
And if you did not create your table using the doctrine command check if $token set to Primary Key in your database.
Related
I need to make a simple insertion in the database,
Here is the code in the controller:
public function verifCreateOrder(Request $req){
$store = 1;
$provider =2;
$creation = $creation_start = $req->get('creation_start');
$delivery = $creation_start = $req->get('creation_start');
$em = $this->getDoctrine()->getManager();
$order = new OrderList();
$order->setNumStore($store);
$order->setNumProvider($provider);
$order->setCreation($creation);
$order->setDelivery($delivery);
$em->persist($order);
$em->flush();
die();
return $this->redirectToRoute('search.view');
}
The code of the OrderList entity :
class OrderList
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="Provider")
* #ORM\JoinColumn(name="num_provider", referencedColumnName="id")
*/
private $numProvider;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="Store")
* #ORM\JoinColumn(name="num_store", referencedColumnName="id")
*/
private $numStore;
/**
* #return int
*/
public function getNumStore()
{
return $this->numStore;
}
/**
* #param int $numStore
*/
public function setNumStore($numStore)
{
$this->numStore = $numStore;
}
/**
* #var \DateTime
*
* #ORM\Column(name="creation", type="date")
*/
private $creation;
/**
* #var \DateTime
*
* #ORM\Column(name="delivery", type="date")
*/
private $delivery;
/**
* #var \DateTime
*
* #ORM\Column(name="last_update", type="date", nullable=true)
*/
private $lastUpdate;
/**
* #var \DateTime
*
* #ORM\Column(name="emission", type="date", nullable=true)
*/
private $emission;
/**
* #var int
*
* #ORM\Column(name="reduction_1", type="integer", nullable=true)
*/
private $reduction1;
/**
* #var int
*
* #ORM\Column(name="reduction_2", type="integer", nullable=true)
*/
private $reduction2;
/**
* #var string
*
* #ORM\Column(name="comment", type="string", nullable=true, length=255)
*/
private $comment;
Here is the error returned by symfony:
Expected value of type "AppBundle\Entity\Provider" for association field "AppBundle\Entity\OrderList#$numProvider", got "integer" instead.
Please help me resolve this error.
You are mixing the Doctrine relation and database foreign key concepts (they are very close, but not the same). The problem is that you can't treat related entity identifier as related entity in Doctrine. You need to pass whole related entity and not just foreign key.
There are at least two solutions:
Instead of passing identifier of store (1) and identifier of provider (2), firstly retrieve this entities from the database ($em->find(...)).
You can trick doctrine with getReference method, that should return you a proxy of needed object with id ($em->getReference('Path\To\Store', 1 and $em->getReference('Path\To\Provider', 2).
If you want more information, you can check these docs: reference proxies and relations.
public function verifyCreateOrder(Request $req){
$storeId = 1;
$providerId = 2;
$creation = $creation_start = $req->get('creation_start');
$delivery = $creation_start = $req->get('creation_start');
$em = $this->getDoctrine()->getManager();
// getting references
$store = $em->getReference(Store::class, $storeId);
$provider = $em->getReference(Provider::class, $providerId);
$order = new OrderList();
$order->setNumStore($store);
$order->setNumProvider($provider);
$order->setCreation($creation);
$order->setDelivery($delivery);
$em->persist($order);
$em->flush();
die();
return $this->redirectToRoute('search.view');
}
I am also new to php but, you set $provider to be a integer = 2, and your relation expect object Provider $provider.
I have an Entity with a primary key like this:
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
* #ORM\Id
*/
protected $productId;
....
/**
* Set productId
*
* #param integer $productId
* #return Products
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return integer
*/
public function getProductId()
{
return $this->productId;
}
But when I try to insert an ProductId with set method, I get this error:
integrity constraint violation 1062 duplicate entry '0' for key 'primary'
I tried with * #ORM\GeneratedValue(strategy="NONE") but the result it's the same, I need to set the Product Id because the sequence isn't 1, 2, 3... is different.
And I can't create a new Id because my current ProductId is used by other entities like Foreing Keys.
Any solution?
Thanks in advance.
-----Edit with the file where I have the error-----
$prod = new Products();
$prod->setProductId("65");
$manager->persist($prod);
$manager->flush();
----Edit with whole Entity----
namespace My\WebBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Products
{
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
protected $productId;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50, nullable=false)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="version", type="integer", nullable=true)
*/
private $version;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=10, nullable=false)
*/
private $code;
/**
* #var integer
*
* #ORM\Column(name="price", type="integer", nullable=false)
*/
private $price;
/**
* Set productId
*
* #param integer $productId
* #return Products
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return integer
*/
public function getProductId()
{
return $this->productId;
}
/**
* Set name
*
* #param string $name
* #return Products
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set version
*
* #param integer $version
* #return Products
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get version
*
* #return integer
*/
public function getVersion()
{
return $this->version;
}
/**
* Set code
*
* #param string $code
* #return Products
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set price
*
* #param integer $price
* #return Products
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return integer
*/
public function getPrice()
{
return $this->price;
}
When using no identifier generation strategy you should not forget that you have to assign the custom ID before you call EntityManagers persist() method.
I think you are persisting the new Entity before assigning the custom ID which means your $productId property is set to null and will be casted to 0 (zero) if you try to flush it. That will cause your error.
Doctrine Doc
Marcus post a good answer to your problem. You can solve it by adding id into you Entity, and use productId as secondary key.
Add id and set it to Auto increment, like
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
Then you can use your productId with:
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
*/
protected $productId;
With this solution you will use $productId as secondary key. Don't forget to clear data in your table.
You also have an error here:
$prod->setProductId(65);
Now you try set data which is string - in your table is integer.
I have a problem, I have a table (downloads) with two fields: Token (primary key) and value.
I have my entity Downloads with these methods (only show token methods, value works right):
/**
* #var string
*
* #ORM\Column(name="token", type="string", length=45, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $token;
/**
* Set token
*
* #param string $token
* #return Downloads
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* Get token
*
* #return string
*/
public function getToken()
{
return $this->token;
}
But, when I do this in my controller:
$em = $this->getDoctrine()->getManager();
$Download = new Downloads();
$Download->setToken($token);
$Download->setValid($now);
$em->persist($Download);
$em->flush();
Object is well created, but in my database Valid is stored correctly, and token is store empty!!
if I see the values, util $em->flush(); object download has two correct values, but after this, token (primary key) disappear his value.
How can I do?
try to remove the #ORM\GeneratedValue
(strategy="IDENTITY") because it is the one that causes doctrine to generate value for Token.
hope it helps :)
you have to create auto increment for your columns like this
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
Stupid answer, but have you tried:
Clearing your Symfony cache
Restarting Apache
It might have to do with Doctrine caching.
I have a user object I am trying to insert via Doctrine.
The key fields are
/**
* #ORM\Column(type="integer", name="id")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $userId;
/**
* #ORM\Id
* #ORM\Column(type="string", name="login_name")
*/
private $loginName;
/**
* #ORM\Column(type="string", name="display_name")
*/
private $name;
In my controller code I can echo out the value of the $loginName field via the getLoginName() method on the object.
/**
* #param mixed $loginName
*/
public function setLoginName($loginName)
{
$this->loginName = $loginName;
}
/**
* #return mixed
*/
public function getLoginName()
{
return $this->loginName;
}
You can see the Controller code to do the insert here.
if ($request->getMethod() == 'POST') {
$form->bind($request);
$login = $form->getData();
$factory = $this->get('security.encoder_factory');
echo($login->getLoginName());
$encoder = $factory->getEncoder($login);
$login->setPassword($encoder->encodePassword($login->getPassword(), $login->getSalt()));
$em = $this->getDoctrine()->getManager();
$em->persist($login);
$em->flush();
$this->get('session')->setFlash(
'success',
'Account Successfully Created'
);
However, when I call persist and flush on my entity, the login_name field is getting '' put into it (empty space). I can't understand why the value is getting nulled out (I changed a DB setting to error when it comes in as non-unique).
There are associations against this class, but this is the primary so I am creating it first.
Any thoughtS?
I don't get what you're doing here. You want table.id to be an auto-generated ID but you want table.login_name to be the primary key? Because that's how you have it setup
#Id is for primary keys
#GeneratedValue defines how priamry keys are created
What I personally think you should want is for table.id to be the primary key, and for table.login_name to be unique
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $userId;
/**
* #ORM\Column(type="string", name="login_name", length=255, unique=true)
*/
private $loginName;
So in testing I identified that you can't apply a generatedValue attribute to an Non-ID field. Once I removed that from the userID field (and allowed Mysql to handle that on it's own) things started to work again.
I have two tables. First table is users and second is datas. Datas has useridx column which is foreign with user's idx. (primary unique key).
These are the table structures:
Table users
CREATE TABLE public.users (
idx bigint NOT NULL,
"name" varchar(250) DEFAULT NULL::character varying,
surname varchar(250) DEFAULT NULL::character varying,
isactive boolean NOT NULL DEFAULT false,
/* Keys */
CONSTRAINT users_pkey
PRIMARY KEY (idx),
CONSTRAINT users_idx_key
UNIQUE (idx)
) WITH (
OIDS = FALSE
);
Table datas:
CREATE TABLE public.datas (
idx bigint NOT NULL,
useridx bigint,
phrase varchar(100) DEFAULT NULL::character varying,
response varchar(100) DEFAULT NULL::character varying,
/* Keys */
CONSTRAINT datas_pkey
PRIMARY KEY (idx),
CONSTRAINT datas_idx_key
UNIQUE (idx),
/* Foreign keys */
CONSTRAINT fk_cf180c1a262768b5
FOREIGN KEY (useridx)
REFERENCES public.users(idx)
ON DELETE NO ACTION
ON UPDATE NO ACTION
) WITH (
OIDS = FALSE
);
Now when i run these commands:
app/console doctrine:mapping:convert yml
./src/Acme/DemoBundle/Resources/config/doctrine/metadata/orm
--from-database
--force
And;
app/console doctrine:mapping:import AcmeDemoBundle annotation
app/console doctrine:generate:entities AcmeDemoBundle
I got this result:
Datas.php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\DemoBundle\Entity\Datas
*
* #ORM\Table(name="datas")
* #ORM\Entity
*/
class Datas
{
/**
* #var bigint $idx
*
* #ORM\Column(name="idx", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="datas_idx_seq", allocationSize="1", initialValue="1")
*/
private $idx;
/**
* #var string $phrase
*
* #ORM\Column(name="phrase", type="string", length=100, nullable=true)
*/
private $phrase;
/**
* #var string $response
*
* #ORM\Column(name="response", type="string", length=100, nullable=true)
*/
private $response;
/**
* #var Users
*
* #ORM\ManyToOne(targetEntity="Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="useridx", referencedColumnName="idx")
* })
*/
private $useridx;
/**
* Get idx
*
* #return bigint
*/
public function getIdx()
{
return $this->idx;
}
/**
* Set phrase
*
* #param string $phrase
*/
public function setPhrase($phrase)
{
$this->phrase = $phrase;
}
/**
* Get phrase
*
* #return string
*/
public function getPhrase()
{
return $this->phrase;
}
/**
* Set response
*
* #param string $response
*/
public function setResponse($response)
{
$this->response = $response;
}
/**
* Get response
*
* #return string
*/
public function getResponse()
{
return $this->response;
}
/**
* Set useridx
*
* #param Acme\DemoBundle\Entity\Users $useridx
*/
public function setUseridx(\Acme\DemoBundle\Entity\Users $useridx)
{
$this->useridx = $useridx;
}
/**
* Get useridx
*
* #return Acme\DemoBundle\Entity\Users
*/
public function getUseridx()
{
return $this->useridx;
}
}
?>
Users.php
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\DemoBundle\Entity\Users
*
* #ORM\Table(name="users")
* #ORM\Entity
*/
class Users
{
/**
* #var bigint $idx
*
* #ORM\Column(name="idx", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="users_idx_seq", allocationSize="1", initialValue="1")
*/
private $idx;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=250, nullable=true)
*/
private $name;
/**
* #var string $surname
*
* #ORM\Column(name="surname", type="string", length=250, nullable=true)
*/
private $surname;
/**
* #var boolean $isactive
*
* #ORM\Column(name="isactive", type="boolean", nullable=false)
*/
private $isactive;
/**
* Get idx
*
* #return bigint
*/
public function getIdx()
{
return $this->idx;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set surname
*
* #param string $surname
*/
public function setSurname($surname)
{
$this->surname = $surname;
}
/**
* Get surname
*
* #return string
*/
public function getSurname()
{
return $this->surname;
}
/**
* Set isactive
*
* #param boolean $isactive
*/
public function setIsactive($isactive)
{
$this->isactive = $isactive;
}
/**
* Get isactive
*
* #return boolean
*/
public function getIsactive()
{
return $this->isactive;
}
}
?>
I also have yml files but i dont think they are necessary in here only PHP files i posted here.
Now, when i run this command inside of my controller:
<?php
$user = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Users')
->find(24);
$phrase = $user->getDatas()->getPhrase();
?>
I got an error that say Call to a member function getDatas() on a non-object.... I know it is clear. In Users.php i don't have getDatas().
But what i read from Symfony2 and Doctrine documentation is it should be there because they are related. All i want to do is get Datas inside of Users.
What is my mistake here? What im missing?
Update:
I added this lines to the Users.php
<?php
/**
* #var \Acme\DemoBundle\Entity\Datas
*
* #ORM\OneToMany(targetEntity="Datas", mappedBy="datas", cascade={"all"})
*/
private $datas;
public function __construct()
{
$this->datas = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add phrases
*
* #param Acme\DemoBundle\Entity\Datas $datas
*/
public function addPhrases(\Acme\DemoBundle\Entity\Datas $datas)
{
$this->datas[] = $datas;
}
/**
* Get datas
*
* #return Doctrine\Common\Collections\Collection
*/
public function getDatas()
{
return $this->datas;
}
?>
And these lines to the Datas.php
<?php
/**
* #ORM\ManyToOne(targetEntity="Users", inversedBy="users", cascade={"all"})
*/
protected $users;
/**
* Set users
*
* #param Acme\DemoBundle\Entity\Users $users
*/
public function setUsers(\Acme\DemoBundle\Entity\Users $users)
{
$this->users = $users;
}
/**
* Get users
*
* #return Acme\DemoBundle\Entity\Users
*/
public function getUsers()
{
return $this->users;
}
?>
Now getDatas() is working but inside of it is not. ($user->getDatas()->getPhrase();)
I am getting this error:
Call to undefined method Doctrine\ORM\PersistentCollection::getPhrase()
Conclusion: I got collection error because it returns a collection -of course-. Iterate (like foreach) it and you will access the data. (If you encounter a problem like this.)
If look at the documentation of #JoinColumn
This annotation is used in the context of relations in #ManyToOne, #OneToOne fields and in the Context of #JoinTable nested inside a #ManyToMany. This annotation is not required. If its not specified the attributes name and referencedColumnName are inferred from the table and primary key names.
So as you are using ManyToOne relation your relation definition would be,
/**
* #var Users
*
* #ORM\ManyToOne(targetEntity="Users")
* #ORM\JoinColumn(name="useridx", referencedColumnName="idx")
*/
private $useridx;
Edit:
If you want to get datas from user side then you have to create OneToMany relation. e.g
In Datas.php
/**
* #var Users
*
* #ORM\ManyToOne(targetEntity="Users", inversedBy = "datas")
* #ORM\JoinColumn(name="useridx", referencedColumnName="idx")
*/
private $useridx;
And in Users.php add following line,
/**
* #ORM\OneToMany(targetEntity="Datas", mappedBy="useridx", cascade={"persist"})
*/
protected $datas;
And then do a doctrine:generate:entities command. To do operations on relation check this doc entry.