Я немного смущен поведением Symfony/Doctrine.
У меня есть форма, которая при отправке отправляет данные обратно контроллеру. Этот контроллер проверяет, содержит ли форма данные нового объекта или того, у кого уже есть идентификатор в базе данных (который ранее был загружен в форму):
if ($form->isValid()) {
if ($sup->getId() > 0) {
return $this->editUserAction($sup);
} else {
return $this->addUserAction($sup);
}
}
Две функции, которые называются, почти равны. Они отличаются только командой persist vs. merge. Интересно, что persist пишет поле, которое не записывается при слиянии:
Существует наследование:
поставщик расширяет компанию, компания расширяет контакт
ORM-мудрая компания - MappedSuperclass, а также контакт - MappedSuperclass (оба абстрактные). Это потому, что поставщик является специализацией компании, которая снова уже специализируется на родовом контакте.
Все значения от поставщика напрямую и наследуемые от контакта записываются в базу данных (всегда). Все значения, поступающие только от компании, записываются в базу данных при вызове persist, но никогда, когда вызывается слияние. В этих классах нет переопределенного свойства.
Это та же форма, которая отправляет данные (создала для этого TypeType: TypeSupplier). Это те же классы и т.д. Определены геттеры и сеттеры (иначе форма не могла установить значения для сохранения). Даже если я вводим одни и те же данные, один раз с нуля и один раз меняя другой объект.
И еще один момент: значение в базе данных не перезаписано нулем. Он просто не изменяется, пока все другие значения будут меняться при слиянии.
Не уверен, что эта информация помогает: Отладчик в phpStorm показывает, что значение задано в переменной $ sup в строке, где вызывается слияние: "Whizzpm\Bundle\Entity\Contact\Company * name1 =" Test value "
public function addUserAction(Supplier $sup)
{
$em = $this->getDoctrine()->getManager();
$em->perist($sup);
$em->flush();
return $this->redirect($this->generateUrl('suppliers_show'));
}
public function editUserAction(Supplier $sup)
{
$em = $this->getDoctrine()->getManager();
$em->merge($sup);
$em->flush();
return $this->redirect($this->generateUrl('suppliers_show'));
}
Вот выдержка компании класса сущностей с двумя значениями, которые не записываются в базу данных при вызове merge:
/**
* Class Company
* @package Whizzpm\Bundle\Entity\Contact
* @ORM\MappedSuperclass
*/
abstract class Company extends Contact {
/**
* @var string
* @ORM\Column(type="string", length=60, nullable=false)
*/
private $name1;
/**
* @var string
* @ORM\Column(type="string", length=60, nullable=true)
*/
private $name2;
/**
* @var integer
* @ORM\Column(type="integer", name="employees", nullable=true)
*/
У кого-нибудь есть идея или какой-либо ресурс, который я могу проверить на помощь здесь? Невозможно найти что-то конкретное в сети. Только общая информация о слиянии и сохранении.
Спасибо за любую помощь!
Не уверен, почему это не сработало слиянием, но я пошел по другому пути:
Здесь результирующий код (я пропустил дополнительную функцию addUserAction/editUserAction, так как обе работают в один момент:
public function showSuppliersAction(Request $request)
{
$sup = null;
if($supplier = $request->request->get('supplier')) {
if(isset($supplier['id'])) {
$sup = $this->getDoctrine()
->getRepository('WhizzpmBundle:Supplier\Supplier')
->findOneById($supplier['id']);
}
}
if(!$sup) {
$sup = new Supplier();
}
$form = $this->createForm(new SupplierType(), $sup);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
$em->persist($sup);
$em->flush();
}
// ....
}