I have an entity called survey
and I have an entity called Creditcards
Creditcard
is linked with survey
using manyToOne
survey
is linked with Creditcard
using oneToMany
The survey has bunch of financial related questions which gets saved in survey
table and it also asks user for their creditcard related details which then gets saved in Creditcard
table, since user can have more than 1 card so they can add multiple card details and this is where the manyToOne
and oneToMany
comes into play.
This is my Creditcard.orm.yml
ExampleBundle\Entity\Creditcards:
type: entity
table: creditcards
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
surveyId:
type: integer
column: survey_id
balance:
type: integer
amountDue:
type: integer
column: amount_due
interestRate:
type: integer
column: interest_rate
manyToOne:
survey:
targetEntity: ExampleBundle\Entity\survey
inversedBy: creditcards
joinColumn:
name: survey_id
referencedColumnName: id
onDelete: CASCADE
lifecycleCallbacks: { }
This is my Creditcard
Entity
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Creditcards
*/
class Creditcards
{
/**
* @var integer
*/
private $id;
/**
* @var integer
*/
private $surveyId;
/**
* @var integer
*/
private $balance;
/**
* @var integer
*/
private $amountDue;
/**
* @var integer
*/
private $interestRate;
/**
* @var \ExampleBundle\Entity\Survey
*/
private $survey;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set surveyId
*
* @param integer $surveyId
* @return integer
*/
public function setSurveyId($surveyId)
{
$this->surveyId = $surveyId;
return $this;
}
/**
* Get survey
*
* @return integer
*/
public function getSurveyId()
{
return $this->surveyId;
}
/**
* Set balance
*
* @param integer $balance
* @return Creditcards
*/
public function setBalance($balance)
{
$this->balance = $balance;
return $this;
}
/**
* Get balance
*
* @return integer
*/
public function getBalance()
{
return $this->balance;
}
/**
* Set amountDue
*
* @param integer $amountDue
* @return Creditcards
*/
public function setAmountDue($amountDue)
{
$this->amountDue = $amountDue;
return $this;
}
/**
* Get amountDue
*
* @return integer
*/
public function getAmountDue()
{
return $this->amountDue;
}
/**
* Set interestRate
*
* @param integer $interestRate
* @return Creditcards
*/
public function setInterestRate($interestRate)
{
$this->interestRate = $interestRate;
return $this;
}
/**
* Get interestRate
*
* @return integer
*/
public function getInterestRate()
{
return $this->interestRate;
}
/**
* Set survey
*
* @param \ExampleBundle\Entity\survey $survey
* @return Creditcards
*/
public function setSurvey(\ExampleBundle\Entity\survey $survey = null)
{
$this->survey = $survey;
return $this;
}
/**
* Get survey
*
* @return \ExampleBundle\Entity\survey
*/
public function getSurvey()
{
return $this->survey;
}
public function addSurvey(\ExampleBundle\Entity\survey $survey)
{
$survey->addCreditcard($this);
$this->survey->add($survey);
}
}
This is my survey.orm.yml
Its pretty long so I will remove some part of it to keep it related to the question
ExampleBundle\Entity\survey:
type: entity
table: survey
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
homeLoanMonthlyRepayments:
type: integer
column: home_loan_monthly_repayments
nullable: true
homeLoanTotalOutstanding:
type: integer
column: home_loan_total_outstanding
nullable: true
carLoanMonthlyRepayments:
type: integer
column: car_loan_monthly_repayments
nullable: true
carLoanTotalOutstanding:
type: integer
column: car_loan_total_outstanding
nullable: true
personalLoanMonthlyRepayments:
type: integer
column: personal_loan_monthly_repayments
nullable: true
personalLoanTotalOutstanding:
type: integer
column: personal_loan_total_outstanding
nullable: true
otherLoanMonthlyRepayments:
type: integer
column: other_loan_monthly_repayments
nullable: true
otherLoanTotalOutstanding:
type: integer
column: other_loan_total_outstanding
nullable: true
userID:
type: integer
column: user_id
nullable: true
oneToOne:
user:
targetEntity: UserBundle\Entity\User
inversedBy: survey
joinColumn:
name: user_id
referencedColumnName: id
oneToMany:
creditcards:
targetEntity: ExampleBundle\Entity\Creditcards
mappedBy: survey
lifecycleCallbacks: { }
This is my survey
Entity
use Doctrine\ORM\Mapping as ORM;
use UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
/**
* survey
*/
class survey
{
/**
* @var integer
*/
private $id;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set homeLoanMonthlyRepayments
*
* @param integer $homeLoanMonthlyRepayments
* @return survey
*/
public function setHomeLoanMonthlyRepayments($homeLoanMonthlyRepayments)
{
$this->homeLoanMonthlyRepayments = $homeLoanMonthlyRepayments;
return $this;
}
/**
* Get homeLoanMonthlyRepayments
*
* @return integer
*/
public function getHomeLoanMonthlyRepayments()
{
return $this->homeLoanMonthlyRepayments;
}
/**
* Set homeLoanTotalOutstanding
*
* @param integer $homeLoanTotalOutstanding
* @return survey
*/
public function setHomeLoanTotalOutstanding($homeLoanTotalOutstanding)
{
$this->homeLoanTotalOutstanding = $homeLoanTotalOutstanding;
return $this;
}
/**
* Get homeLoanTotalOutstanding
*
* @return integer
*/
public function getHomeLoanTotalOutstanding()
{
return $this->homeLoanTotalOutstanding;
}
/**
* Set carLoanMonthlyRepayments
*
* @param integer $carLoanMonthlyRepayments
* @return survey
*/
public function setCarLoanMonthlyRepayments($carLoanMonthlyRepayments)
{
$this->carLoanMonthlyRepayments = $carLoanMonthlyRepayments;
return $this;
}
/**
* Get carLoanMonthlyRepayments
*
* @return integer
*/
public function getCarLoanMonthlyRepayments()
{
return $this->carLoanMonthlyRepayments;
}
/**
* Set carLoanTotalOutstanding
*
* @param integer $carLoanTotalOutstanding
* @return survey
*/
public function setCarLoanTotalOutstanding($carLoanTotalOutstanding)
{
$this->carLoanTotalOutstanding = $carLoanTotalOutstanding;
return $this;
}
/**
* Get carLoanTotalOutstanding
*
* @return integer
*/
public function getCarLoanTotalOutstanding()
{
return $this->carLoanTotalOutstanding;
}
/**
* Set personalLoanMonthlyRepayments
*
* @param integer $personalLoanMonthlyRepayments
* @return survey
*/
public function setPersonalLoanMonthlyRepayments($personalLoanMonthlyRepayments)
{
$this->personalLoanMonthlyRepayments = $personalLoanMonthlyRepayments;
return $this;
}
/**
* Get personalLoanMonthlyRepayments
*
* @return integer
*/
public function getPersonalLoanMonthlyRepayments()
{
return $this->personalLoanMonthlyRepayments;
}
/**
* Set personalLoanTotalOutstanding
*
* @param integer $personalLoanTotalOutstanding
* @return survey
*/
public function setPersonalLoanTotalOutstanding($personalLoanTotalOutstanding)
{
$this->personalLoanTotalOutstanding = $personalLoanTotalOutstanding;
return $this;
}
/**
* Get personalLoanTotalOutstanding
*
* @return integer
*/
public function getPersonalLoanTotalOutstanding()
{
return $this->personalLoanTotalOutstanding;
}
/**
* Set otherLoanMonthlyRepayments
*
* @param integer $otherLoanMonthlyRepayments
* @return survey
*/
public function setOtherLoanMonthlyRepayments($otherLoanMonthlyRepayments)
{
$this->otherLoanMonthlyRepayments = $otherLoanMonthlyRepayments;
return $this;
}
/**
* Get otherLoanMonthlyRepayments
*
* @return integer
*/
public function getOtherLoanMonthlyRepayments()
{
return $this->otherLoanMonthlyRepayments;
}
/**
* Set otherLoanTotalOutstanding
*
* @param integer $otherLoanTotalOutstanding
* @return survey
*/
public function setOtherLoanTotalOutstanding($otherLoanTotalOutstanding)
{
$this->otherLoanTotalOutstanding = $otherLoanTotalOutstanding;
return $this;
}
/**
* Get otherLoanTotalOutstanding
*
* @return integer
*/
public function getOtherLoanTotalOutstanding()
{
return $this->otherLoanTotalOutstanding;
}
/**
* @var integer
*/
private $userID;
/**
* Set userID
*
* @param integer $userID
* @return survey
*/
public function setUserID($userID)
{
$this->userID = $userID;
return $this;
}
/**
* Get userID
*
* @return integer
*/
public function getUserID()
{
return $this->userID;
}
/**
* @var \UserBundle\Entity\User
*/
private $user;
/**
* @var \ExampletBundle\Entity\Creditcards
*/
private $creditcards;
/**
* Set user
*
* @param \UserBundle\Entity\User $user
* @return survey
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
public function __toString()
{
return (string) $this->getUser();
}
/**
* Constructor
*/
public function __construct()
{
$this->creditcards = new ArrayCollection();
}
/**
* Add creditcards
*
* @param \ExampletBundle\Entity\Creditcards $creditcards
* @return survey
*/
public function addCreditcard(\ExampleBundle\Entity\Creditcards $creditcards)
{
if (!$this->creditcards->contains($creditcards)) {
$this->creditcards->add($creditcards);
}
return $this;
}
/**
* Remove creditcards
*
* @param \ExampletBundle\Entity\Creditcards $creditcards
*/
public function removeCreditcard(\ExampleBundle\Entity\Creditcards $creditcards)
{
$this->creditcards->removeElement($creditcards);
}
/**
* Get creditcards
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCreditcards()
{
return $this->creditcards;
}
}
The Form that gets called in controller and passed to the twig
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class debtType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('homeLoanMonthlyRepayments')
->add('homeLoanTotalOutstanding')
->add('carLoanMonthlyRepayments')
->add('carLoanTotalOutstanding')
->add('personalLoanMonthlyRepayments')
->add('personalLoanTotalOutstanding')
->add('otherLoanMonthlyRepayments')
->add('otherLoanTotalOutstanding')
->add('creditcards', 'collection', array('type' => new CreditcardsType(), 'allow_add' => true, 'by_reference' => false,
));
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'ExampleBundle\Entity\survey'
));
}
/**
* @return string
*/
public function getName()
{
return 'examplebundle_debt';
}
}
Finally my debtAction
that processes the form and tries to save the data
public function debtAction(Request $request){
$em = $this->getDoctrine()->getManager();
//get user id of currently logged in user
$userId = $this->getUser()->getId();
//get survey object of currently logged in user
$userExpensesInfo = $em->getRepository('ExampleBundle:survey')->findOneByuserID($userId);
$form = $this->createForm(new debtType(), $userExpensesInfo);
$form->handleRequest($request);
if($request->isMethod('POST')){
if($form->isValid()){
$userExpensesInfo->setExpenseFood($form->get('homeLoanMonthlyRepayments')->getData());
$userExpensesInfo->setExpenseFood($form->get('homeLoanTotalOutstanding')->getData());
$userExpensesInfo->setExpenseHousing($form->get('carLoanMonthlyRepayments')->getData());
$userExpensesInfo->setExpenseTransport($form->get('carLoanTotalOutstanding')->getData());
$userExpensesInfo->setExpenseFun($form->get('personalLoanMonthlyRepayments')->getData());
$userExpensesInfo->setExpenseClothing($form->get('personalLoanTotalOutstanding')->getData());
$userExpensesInfo->setExpenseUtil($form->get('otherLoanMonthlyRepayments')->getData());
$userExpensesInfo->setExpensePersonal($form->get('otherLoanTotalOutstanding')->getData());
$userExpensesInfo->getCreditcards()->add($form->get('creditcards')->getData());
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Your loan information has been saved'
);
return $this->render('ExampleBundle:Default/dashboard:debt.html.twig', array(
'form'=>$form->createView(),
));
}
}
return $this->render('ExampleBundle:Default/dashboard:debt.html.twig', array(
'form'=>$form->createView(),
));
}
I have gone through step by step through this article but I just cant get the save to work, when I try to save it this is the error I get
A new entity was found through the relationship 'ExampleBundle\Entity\survey#creditcards' that was not configured to cascade persist operations for entity: ExampleBundle\Entity\Creditcards@000000001bbd76da000000008bbf1e28. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'ExampleBundle\Entity\Creditcards#__toString()' to get a clue.
500 Internal Server Error - ORMInvalidArgumentException
The article I refereed above does talk about it at this section, I followed the instruction and no matter what I do I just cant get passed this error. Its over 6 hours now that I am trying to solve this and I just cant think straight any more.
I will really appreciate if I can get some here on this.
UPDATE:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
bundles: [ ExampleBundle ]
#java: /usr/bin/java
filters:
cssrewrite: ~
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }