Reputation: 93
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
Upvotes: 1
Views: 54
Reputation: 4957
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();
Upvotes: 1