Multiple persist in Symfony 3 Doctrine - symfony

I have a database with 3 tables, Equipment, transaction and transactionReceive. In the future there will be multiple transactionXYZ, one for each type of transaction. I used a joined inheritance to link transactionReceive with transaction. I also use a Many to one association between Equipment and transaction, since a piece of equipment can have multiple transactions.
I am currently working on adding a piece of equipment. This is a two step process. It should:
1: Create the piece of equipment
2: Create the transaction/transactionReceive
My issue is that when I try to set the equipmentId to persist the transaction, it throws an exception saying it is null.
My code is as follow:
$em->persist($equipmentData);
$em->flush();
$trans = new TransactionReceive();
$trans->setEquipmentId($equipmentData->getId());
//Here I set all transactions info
$em->persist($trans);
$em->flush();
Thanks
EDIT:
Apparently my issue would be related to the insert with the ManyToOne association. I noticed it because I get the same error even if I hardcode a value for the equipmentId in the transaction.
EDIT 2:
Transaction entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Transaction
*
* #ORM\Table(name="transaction")
* #ORM\Entity(repositoryClass="AppBundle\Repository\TransactionRepository")
*
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="transactionType", type="string")
* ORM\#DiscriminatorMap({
* "receive" = "TransactionReceive",
* "changeout" = "TransactionChangeoutWheelset",
* })
*/
class Transaction
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
* #ORM\ManyToOne(targetEntity="Equipment")
* #ORM\Column(name="equipmentId", type="integer")
*/
private $equipmentId;
/**
* #return int
*/
public function getequipmentId()
{
return $this->equipmentId;
}
/**
* #param int $equipmentId
*
* #return self
*/
public function setEquipmentId($equipmentId)
{
$this->equipmentId= $equipmentId;
return $this;
}
// Other attributes, getters and setters
TransactionReceive entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Transaction;
/**
* TransactionReceive
*
* #ORM\Table(name="transaction_receive")
* #ORM\Entity(repositoryClass="AppBundle\Repository\TransactionReceiveRepository")
*/
class TransactionReceive extends Transaction
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="gsThickness", type="integer")
*/
private $gsThickness;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set gsThickness
*
* #param integer $gsThickness
*
* #return TransactionReceive
*/
public function setGsThickness($gsThickness)
{
$this->gsThickness = $gsThickness;
return $this;
}
/**
* Get gsThickness
*
* #return int
*/
public function getGsThickness()
{
return $this->gsThickness;
}
}

Since your equipementId proprety is a foreign key, you need to set it to an object equipement, not only it's Id.
Replacing the line $trans->setEquipmentId($equipmentData->getId()); by
$trans->setEquipmentId($equipmentData);
should do the trick for you.

Related

not defined as association in doctrine orm validate

i have two entities named UserCode and Question that have relation between question columns and when i run doctrine:schema:validate it s ok
but my problem is when i add
#ORM\Entity(repositoryClass="AppBundle\Repository\UserCodeRepository")
at top of UserCode entity i get this error !!
* The association AppBundle\Entity\UserCode#question refers to the inverse side field AppBundle\Entity\Question#question which is not defined as association.
* The association AppBundle\Entity\UserCode#question refers to the inverse side field AppBundle\Entity\Question#question which does not exist.
Question entity :
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\UserCode;
/**
* Question
*
* #ORM\Table(name="question")
* #ORM\Entity(repositoryClass="AppBundle\Repository\QuestionRepository")
*/
class Question
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="question", type="text")
* #ORM\OneToMany(targetEntity="AppBundle\Entity\UserCode", mappedBy="question")
*/
private $question;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set question
*
* #param string $question
*
* #return Question
*/
public function setQuestion($question)
{
$this->question = $question;
return $this;
}
/**
* Get question
*
* #return string
*/
public function getQuestion()
{
return $this->question;
}
}
and this is my UserCode entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
use Symfony\Component\Validator\Constraints as Assert;
/**
* UserCode
*
* #ORM\Table(name="user_code")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserCodeRepository")
*/
class UserCode
{
/**
* #var int
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Question", inversedBy="question")
* #ORM\JoinColumn(name="question", referencedColumnName="id")
*/
private $question;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set question
*
* #param \AppBundle\Entity\Question $question
*
* #return UserCode
*/
public function setQuestion(\AppBundle\Entity\Question $question = null)
{
$this->question = $question;
return $this;
}
/**
* Get question
*
* #return \AppBundle\Entity\Question
*/
public function getQuestion()
{
return $this->question;
}
}
remove
#ORM\JoinColumn(name="question", referencedColumnName="id")
from
UserCode entity and
* #var string
*
* #ORM\Column(name="question", type="text")
from question entity
it will work perfectly :)

is possible use setId() for id in doctrine entity?

I want to set id manual I write this code in my Test entity:
can I use setId() for entities like my code?
My code is here:
/**
* Test
* #ORM\Table(name="test")
*/
class Test
{
/**
* #var int
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Set id
* #param integer $id
* #return Test
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
* #return integer
*/
public function getId()
{
return $this->id;
}
// other methods
}
is this correct way to set id?
if not what is the correct and standard way?
You can use your own primary key, telling to Doctrine not to generate value ...
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/annotations-reference.html#annref_generatedvalue
/**
* Test
* #ORM\Table(name="test")
*/
class Test
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* Set id
* #param integer $id
* #return Test
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
Don't forget setId before persist!
Doctrine expects the primary key of your entity to be immutable (non-changeable) after the entity is persisted/flushed to the database (or fetched from DB).
The code you wrote is perfectly correct in terms of PHP but will most likely break doctrine functionality if you ever use setId().
If you are interested in the internals, look up "Doctrine identity maps"

Doctrine OneToOne drives me crazy

I know that is a recurrent question but after creating a OneToOne relation between 2 entities and run 'php app/console doctrine:schema:validate' I get this error:
'[Mapping] FAIL - The entity-class 'HO\CisBundle\Entity\AffiliateSalesAccounts' mapping is invalid:
* The association HO\CisBundle\Entity\AffiliateSalesAccounts#affiliate refers to the inverse side field HO\HasoffersBundle\Entity\Affiliate#affiliateSalesAccounts which does not exist.'
This is part of the code with both entities:
AffiliatesSalesAccount Entity
namespace HO\CisBundle\Entity;
use HO\HasoffersBundle\Entity\Affiliate;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Table(name="AffiliateSalesAccounts")
* #ORM\Entity()
* #ORM\HasLifecycleCallbacks
*/
class AffiliateSalesAccounts {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* #var \HO\HasoffersBundle\Entity\Affiliate
*
* #ORM\OneToOne(targetEntity="HO\HasoffersBundle\Entity\Affiliate", inversedBy="affiliateSalesAccounts")
* #ORM\JoinColumn(name="affiliate_id", referencedColumnName="id")
*
*/
private $affiliate;
...
/**
* #param Affiliate $affiliate
*/
public function setAffiliate(Affiliate $affiliate)
{
$this->affiliate = $affiliate;
}
/**
* #return Affiliate
*/
public function getAffiliate()
{
return $this->affiliate;
}
}
Affiliate Entity
namespace HO\HasoffersBundle\Entity;
use HO\CisBundle\Entity\AffiliateSalesAccounts;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Table(name="ho_Affiliate")
*/
class Affiliate
{
/**
* #var AffiliateSalesAccounts
*
* #ORM\OneToOne(targetEntity="HO\CisBundle\Entity\AffiliateSalesAccounts", mappedBy="affiliate")
*/
private $affiliateSalesAccounts;
....
/**
* #param \HO\CisBundle\Entity\AffiliateSalesAccounts $affiliateSalesAccounts
*/
public function setAffiliateSalesAccounts($affiliateSalesAccounts)
{
$this->affiliateSalesAccounts = $affiliateSalesAccounts;
}
/**
* #return \HO\CisBundle\Entity\AffiliateSalesAccounts
*/
public function getAffiliateSalesAccounts()
{
return $this->affiliateSalesAccounts;
}
}
I have other similar OneToOne relations between 2 entities and it works great.
Someone can I help me?
Thanks a lot..
I am not sure about your problem but I notice that I do it in a different way I just let the code here so that you will be able to check it
/**
* #ORM\OneToOne(targetEntity="Profile", mappedBy="user", cascade={"remove"})
**/
private $profile;
The other class:
/**
* #var \Lifecrops\LCUserBundle\Entity\User
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Lifecrops\LCUserBundle\Entity\User", inversedBy="profile")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="User_id", referencedColumnName="id")
* })
*/
private $user;
Ussually I do something like this:
namespace HO\CisBundle\Entity;
use HO\HasoffersBundle\Entity\Affiliate;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="AffiliateSalesAccounts")
* #ORM\Entity()
*/
class AffiliateSalesAccounts {
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Affiliate", inversedBy="affiliateSalesAccounts")
* #ORM\JoinColumn(name="affiliate_id", referencedColumnName="id")
*
*/
private $affiliate;
/**
* #param Affiliate $affiliate
*/
public function setAffiliate(Affiliate $affiliate)
{
$this->affiliate = $affiliate;
}
/**
* #return Affiliate
*/
public function getAffiliate()
{
return $this->affiliate;
}
}
And the second entity:
namespace HO\HasoffersBundle\Entity;
use HO\CisBundle\Entity\AffiliateSalesAccounts;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="ho_Affiliate")
* #ORM\Entity()
*/
class Affiliate
{
/**
* #ORM\OneToOne(targetEntity="AffiliateSalesAccounts", mappedBy="affiliate")
*/
private $affiliateSalesAccounts;
/**
* #param AffiliateSalesAccounts $affiliateSalesAccounts
*/
public function setAffiliateSalesAccounts($affiliateSalesAccounts)
{
$this->affiliateSalesAccounts = $affiliateSalesAccounts;
}
/**
* #return AffiliateSalesAccounts
*/
public function getAffiliateSalesAccounts()
{
return $this->affiliateSalesAccounts;
}
}
Clearing cache is imortant part, and if all goes bad you can look to:
doctrine:
orm:
auto_mapping: true
Ok, I solved the problem... First, sorry for bothering you because it was a stupid silly absent-mindedness... Since we use Redis to cache doctrine (with sncRedisBundle), specially metadata and query, Affiliate entity was cached in Redis but without the new field declaration "affiliateSalesAccounts". After deleting the key which store Affiliate entity the problem was solved.
Thank so much for your comments

Symfony 2 doctrine persist doesn't work after updating Relationship Mapping

I updated my entity file to include relationship mapping.
Persist worked before the update now it doesn't.
Maybe it's something I forgot to do.
namespace classes\classBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* advisersplans
*
* #ORM\Table()
* #ORM\Entity
*/
class advisersPlans
{
/**
*
* #ORM\ManyToOne(targetEntity="plans", inversedBy="adviserPlans")
* #ORM\JoinColumn(name="planid", referencedColumnName="id")
*/
public $plan;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var integer
*
* #ORM\Column(name="userid", type="integer")
*
*
*/
public $userid;
/**
* #var integer
*
* #ORM\Column(name="adviserid", type="integer")
*
*
*/
public $adviserid;
/**
* #var integer
*
* #ORM\Column(name="planid", type="integer")
*
*
*/
public $planid;
/**
* #var string
*
* #ORM\Column(name="participantLoginWebsiteAddress", type="string", length=255)
*/
public $participantLoginWebsiteAddress;
public function __construct()
{
$class_vars = get_class_vars(get_class($this));
foreach ($class_vars as $key => $value)
{
if ($key != "plan")
$this->$key = "";
}
}
}
Perist returns error saying planid is null. If I remove the following it works.
/**
*
* #ORM\ManyToOne(targetEntity="plans", inversedBy="adviserPlans")
* #ORM\JoinColumn(name="planid", referencedColumnName="id")
*/
Here is my code while persisting.
$adviserPlan = new advisersPlans();
$adviserPlan->planid = $planid;
$adviserPlan->userid = $this->userid();
$adviserPlan->adviserid = $session->get("editadviserid");
$em->persist($adviserPlan);
Am I supposed to populate the plan field and not the planid field or is my entity file coded wrong.
You shouldn't set ids. You should set entities:
$adviserPlan = new advisersPlans();
// You should retrieve the plan before doing this, of course.
$adviserPlan->setPlan($plan);
$plans->addAdviserPlan(§adviserPlan);
$em->persist($adviserPlan);
The methods for adding an entity to a collection should be generated by doctrine when you run:
php app/console doctrine:generate:entities YourBundle

Add field with OneToOne relation in FOSUser register form

I need your help to add some field in my register form in FOSUSerBundle.
I want to localize a user and save his latitude/longitude in the register form.
I create a oneToOne relation between my User entity and my Localisation entity, but I don't see where I could put my code to set the latitude and longitude of the user at the register phase.
Did I have to override the register controller, or some event ? I just don't see where put my code...
First, the documentation here is not updated for the new signature method : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_controllers.md
This tutorial is ok but I don't see how use it with a oneToOne field... :
http://www.idci-consulting.fr/fosuserbundle-comment-gerer-les-utilisateurs-avec-symfony2/
In fact, I add my relation in the User entity used for FOSUserBundle :
<?php
namespace rs\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use FOS\MessageBundle\Model\ParticipantInterface;
/**
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser implements ParticipantInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToOne(targetEntity="rs\UserBundle\Entity\Localisation", cascade={"persist"})
*/
protected $localisation;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set localisation
*
* #param \rs\UserBundle\Entity\Localisation $localisation
* #return User
*/
public function setLocalisation(\rs\UserBundle\Entity\Localisation $localisation = null)
{
$this->localisation = $localisation;
return $this;
}
/**
* Get localisation
*
* #return \rs\UserBundle\Entity\Localisation
*/
public function getLocalisation()
{
return $this->localisation;
}
}
Here is my Localisation entity :
<?php
namespace rs\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Localisation
*
* #ORM\Table()
* #ORM\Entity
*/
class Localisation
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var float
*
* #ORM\Column(name="latitude", type="decimal")
*/
private $latitude;
/**
* #var float
*
* #ORM\Column(name="longitude", type="decimal")
*/
private $longitude;
/**
* #var integer
*
* #ORM\OneToOne(targetEntity="rs\UserBundle\Entity\Clan", cascade={"persist"})
*/
private $clan;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set latitude
*
* #param float $latitude
* #return Localisation
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* #return float
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longitude
*
* #param float $longitude
* #return Localisation
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
return $this;
}
/**
* Get longitude
*
* #return float
*/
public function getLongitude()
{
return $this->longitude;
}
/**
* Set clan
*
* #param \rs\UserBundle\Entity\Clan $clan
* #return Localisation
*/
public function setClan(\robStorm\UserBundle\Entity\Clan $clan = null)
{
$this->clan = $clan;
return $this;
}
/**
* Get clan
*
* #return \rs\UserBundle\Entity\Clan
*/
public function getClan()
{
return $this->clan;
}
}
Thanks ;)
You have to override/extend the existing RegistrationFormType. See overriding forms in the docs. In your type you add the location as sub form. So you have to create a LocationFormType too.
If you need to process some logig, you have to hook into the controller with events. Unfortunately events are only available in dev-master yet, not in the stable releases. If you forced to use the stable release, you have to override the controller and copy all the logic from the old one and then add your logic.

Resources