我目前正在努力正确设置实体。情况如下:
"国家"有一个或多个"客户">
我有一个包含所有国家/地区的国家/地区表,我想为每个客户保存一个国家/地区参考。非常简单而且经常需要。
但我无法正确配置实体。如果我没有在"Customer"类中定义级联方法,我会得到一个异常。如果我添加级联方法,那么国家/地区对象也会作为新记录添加到国家/地区表中,但我只想在Customer表中引用该对象。
客户类别
/**
* @ORMEntity
* @ORMTable(name="PS_Customer")
*/
class Customer {
/**
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
* @ORMColumn(type="integer")
*/
protected $id;
/**
* @ORMManyToOne(targetEntity="Country",inversedBy="id")
* @ORMJoinColumn(name="country_id", referencedColumnName="id")
*/
protected $country;
}
国家级
/**
* @ORMEntity
* @ORMTable(name="PS_Country")
*/
class Country {
/**
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
* @ORMColumn(type="integer")
* @ORMOneToMany(targetEntity="Customer", mappedBy="country")
*/
protected $id;
/** @ORMColumn(type="string") */
protected $name;
/** @ORMColumn(type="string") */
protected $iso2;
}
如果我想用这个定义存储Customer对象,我会收到以下错误:
A new entity was found through the relationship 'PhotoshopEntityCustomer#country' that was not configured to cascade persist operations for entity: PhotoshopEntityCountry@000000004c6f8efb00000000b695d273. 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 'PhotoshopEntityCountry#__toString()' to get a clue.
ActionController(已提取):
$forms = $this->getServiceLocator()->get('FormElementManager');
$form = $forms->get('PhotoshopFormCheckoutForm');
$customer = new Customer;
$form->bind($customer);
$order = new Order;
$order->setCustomer($customer);
// Order object is put into a session during checkout process here...
/**
* Commit Order to database
*/
$em = $this->getServiceLocator()->get('DoctrineORMEntityManager');
$em->persist($sessionCheckout->order); // Fetch the order object from session
$em->flush();
结账表单
class CheckoutForm extends Form implements ObjectManagerAwareInterface {
protected $objectManager;
public function __construct() {
parent::__construct('checkout');
}
public function init() {
$this->setAttribute('action', 'checkout');
$this->setAttribute('method', 'post');
$this->setHydrator(new DoctrineHydrator($this->getObjectManager()));
$this->setInputFilter(new PhotoshopFormCheckoutFilter());
$this->add(array(
'name' => 'country',
'type' => 'DoctrineModuleFormElementObjectSelect',
'options' => array(
'label' => 'Country:',
'empty_option' => 'Please choose...',
'object_manager' => $this->getObjectManager(),
'target_class' => 'PhotoshopEntityCountry',
'property' => 'name',
),
));
$this->add(array(
'type' => 'ZendFormElementSelect',
'name' => 'gender',
'options' => array(
'label' => 'Title*:',
'empty_option' => 'Please choose...',
'value_options' => array(
'f' => 'Mrs.',
'm' => 'Mr.'
),
)
));
$this->add(array(
'name' => 'firstName',
'attributes' => array(
'type' => 'text',
'id' => 'firstName'
),
'options' => array(
'label' => 'First name*:'
),
));
$this->add(array(
'name' => 'lastName',
'attributes' => array(
'type' => 'text',
'id' => 'lastName'
),
'options' => array(
'label' => 'Last name*:'
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Pay with PayPal or Credit Card now',
'class' => 'btn btn-primary btn-lg btn-block'
)
));
}
public function setObjectManager(ObjectManager $objectManager) {
$this->objectManager = $objectManager;
}
/**
* Get the object manager
*
* @return ObjectManager
*/
public function getObjectManager() {
return $this->objectManager;
}
}
我确信这将是一个简单的解决方案。但我目前看不到解决方案:)
也许有人能给我一个提示?!?非常感谢。。。
谢谢,Michael
//订单对象在这里的结账过程中被放入会话中…----这是的重要部分
所以,如果我理解的话,您在一个请求中创建订单和客户,然后通过会话将其转移到另一个请求,并将其保存在那里。实际发生的情况是,您有一个对象图,如order->customer->country,其中前两个是新实体,所以序列化非序列化对它们没有任何问题,但country是DB中已经存在的托管实体。通过将它序列化到会话中,它将与实体管理器分离,在取消序列化后,它将被呈现给新的实体管理器实例,该实例不知道它曾经被管理过,因此决定将其作为新实例进行持久化。
通常,您需要将未序列化的实体合并到当前实体管理器
$managedOrder = $em->merge($sessionCheckout->order);
并使用$managedOrder。为此,您可能需要在Customer::country和Order::Customer上设置cascade={"merge"}。
条令中有关于这一主题的实体会议文件页面。