简体   繁体   中英

Store entity from session doesn't work => $em->persist()

at first: Sorry for my poor english :-)

A beginner need help!

I have 3 entities/tables:

Tables:

contact_person
id, title, firstname, surname, adress_id

address
id, street, zip, city, country_id

country (fix values)
id, name, code
1, Austria, AT
2, Germany, DE
...

Entities:

/**
 * ContactPerson
 *
 * @ORM\Table(name="contact_person")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class ContactPerson
{
    /**
     * @var integer $contactPersonId
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $contactPersonId;

    /**
     * @ORM\Column(name="title", type="string", columnDefinition="ENUM('m', 'w')")
     */
    private $title;

    /**
     * @ORM\Column(name="firstname", type="string", length=255)
     */
    private $firstName;

    /**
     * @ORM\Column(name="surname", type="string", length=255)
     */
    private $surName;

    /**
     * @ORM\OneToOne(targetEntity="Trac\TracBundle\Entity\Address", cascade={"persist"})
     * @ORM\JoinColumn(name="address_id", referencedColumnName="id")
     */
    protected $address;

    ...
}

/**
 * Address
 *
 * @ORM\Table(name="address")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Address
{
    /**
     * @var integer $addresssId
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $addresssId;

    /**
     * @ORM\Column(name="street", type="string", length=255)
     */
    private $street;

    /**
     * @ORM\Column(name="zip", type="string", length=255)
     */
    private $zip;

    /**
     * @ORM\Column(name="city", type="string", length=255)
     */
    private $city;

    /**
     * @ORM\ManyToOne(targetEntity="Trac\TracBundle\Entity\Country", inversedBy="addresses", cascade={"persist"})
     * @ORM\JoinColumn(name="country_id", referencedColumnName="id", nullable=true)
     */
    private $country;

    ...
}

/**
 * Country
 *
 * @ORM\Table(name="country")
 * @ORM\Entity
 */
class Country
{
    /**
     * @var integer $countryId
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $countryId;

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(name="code", type="string", length=255)
     */
    private $code;

    ...
}

1 Form:

ContactPersonType:

$builder->add('title', 'choice', array('choices'  => array('m' => 'male', 'w' => 'female')));
$builder->add('firstname', 'text');
$builder->add('surname', 'text');
$builder->add('address', new \myBundle\Form\AddressType(), array(
    'data_class' => 'myBundle\Entity\Address'
));

AddressType:

$builder->add('street', 'text');
$builder->add('zip', 'text');
$builder->add('city', 'text');
$builder->add('country', 'entity', array(
    'class' => 'myBundle\Entity\Country',
    'property' => 'name'
));

CountryType:

$builder->add('country', 'entity', array(
    'class' => 'myBundle\Entity\Country',
    'property' => 'name'
));

When i do a form-post the controller stores the request-data successfully in tables. All works fine!

ContactPersonController:

$form->handleRequest($request);
if($form->isValid()) {

    $contact_person = $form->getData();

    $em->persist($contact_person);
    $em->flush();
}

Result in tables:

contact_person
id, title, firstname, surname, adress_id
1, Mr, Ted, Tester, 1

address
id, street, zip, city, country_id
1, myStreet, 12345, Berlin, 2

country
id, name, code
1, Austria, AT
2, Germany, DE

PROBLEM:

When i store the contact person-entities in session and call $em->persist() from another controller, the country-mapping failed:

ContactPersonController (store contact person-objects into session):

$form->handleRequest($request);
$session = $request->getSession();
if($form->isValid()) {
    $contactPersons[] = $form->getData();
    //Add to session
    $session->set('contactPersons', $contactPersons);
}

AnotherController:

...

if($form->isValid()) {

    $customer = $form->getData();

    //Customer
    $em->persist($customer);
    $em->flush();

    //Get contact persons from session
    $contactPersons = $session->get('contactPersons');

    //Save contact persons to tables
    if(is_array($contactPersons) && !empty($contactPersons)) {

        foreach($contactPersons as $key => $contactPerson) {
            $em->persist($contactPerson);
            $em->flush();
        }
    }
}

...

Wrong result into tables

contact_person
id, title, firstname, surname, adress_id
1, Mr, Ted, Tester, 1

address
id, street, zip, city, country_id
1, myStreet, 12345, Berlin, 3

country
id, name, code
1, Austria, AT
2, Germany, DE
3, Germany, DE <= Create a new row... BUT WHY??? it should reference the id 2 by mapping into address (country_id)

Thans for help,

gondor

When you store doctrine entities in the session they become detached from the EntityManager. You need to merge any entities which are already in the database back into the EntityManager. Something like this (checking for null where necessary):

    foreach($contactPersons as $key => $contactPerson) {
        $mergedCountry = $em->merge($contactPerson->getAddress()->getCountry());
        $contactPerson->getAddress()->setCountry($mergedCountry);
        $em->persist($contactPerson);
    }
    $em->flush();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM