douying3251 2015-09-21 10:15
浏览 34
已采纳

Symfony无法保存manyToOne双向实体

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 }
  • 写回答

3条回答 默认 最新

  • douxiegan6468 2015-09-23 10:55
    关注

    I finally got it to work. It seems that I was not saving the credit card details by using Symfony properly.

    Inside my controller I was setting up the data manually which was totally not required in my case

    $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());       
    

    Then I had to change my function addCreditCard to as following

    public function addCreditCard(CreditCard $card)
    {
        if (!$this->creditcards->contains($card)) {
            $this->creditcards->add($card);
        }
        $card->setSurvey($this);
    }         
    

    After than it was working perfectly fine.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 matlab答疑 关于海上风电的爬坡事件检测
  • ¥88 python部署量化回测异常问题
  • ¥30 酬劳2w元求合作写文章
  • ¥15 在现有系统基础上增加功能
  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄