2015-05-12 23 views
5

Tôi có một Người dùng thực thể học thuyết, thực hiện AdvancedUserInterface. Thực thể có một trường thuộc tính của lớp UserProperties, được ánh xạ dưới dạng loại đối tượng.Cách cập nhật trường loại đối tượng giáo lý

Entity tôi:

class User implements AdvancedUserInterface, \Serializable { 
<....> 
    /** 
    * @var UserProperties 
    * 
    * @ORM\Column(name="properties", type="object", nullable=true, options={"default":null}) 
    */ 
    private $properties; 
<....> 
} 

Thuộc tính lớp:

class UserProperties { 
    public $isEmailVisible = false; 
    public $isNameVisible = false; 
} 

Nếu tính giá trị trong cơ sở dữ liệu là rỗng và tôi làm một số thay đổi đối với thiết lập các thuộc tính đối tượng thực thể - nó hoạt động tốt. Nhưng nếu tôi cam kết một số thay đổi đối với cơ sở dữ liệu và trường thuộc tính là NOT null (đã có một đối tượng UserProperties được tuần tự hóa) - các thay đổi không được lưu (nhưng tất cả các thay đổi khác trên thực thể Người dùng).

Tôi làm gì sai?

Trả lời

5

Chính sách theo dõi kiểm tra Doctrine có hay không một đối tượng đã thay đổi, trong trường hợp của bạn - User lớp. Tuy nhiên, khi kiểm tra nếu $this->properties đã thay đổi tất cả các Doctrine không kiểm tra xem nó vẫn trỏ đến cùng một đối tượng trong bộ nhớ (!).

Nếu bạn muốn buộc nó để cập nhật đối tượng được lưu trữ, bạn có thể sao chép tất cả các thuộc tính của nó vào một trường hợp đối tượng mới (new UserProperties và sau đó gán lại sách cho $this->properties), sao chép nó, hoặc thay đổi theo dõi chính sách để NOTIFY thuyết (xem http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/change-tracking-policies.html).

Tuy nhiên, cuối cùng, sẽ yêu cầu bạn thay đổi tất cả các trình lắng nghe của đối tượng và thực sự triển khai cơ chế thông báo (như được hiển thị trong tài liệu Doctrine), khi vấn đề này xuất hiện trong mã của tôi, tôi vừa tạo lại đối tượng được lưu trữ. gợi ý đầu tiên, vì nó đơn giản). Tuy nhiên, tôi nghĩ rằng đây là loại hành vi không mong muốn, vì vậy tôi sẽ mở một vé/vấn đề trong trình theo dõi vấn đề Doctrine, để ít nhất một tài liệu cảnh báo về điều này.

5

Vấn đề ở đây là Doctrine không kiểm tra xem các giá trị của đối tượng tuần tự đã thay đổi chưa, nó chỉ kiểm tra xem đối tượng có cùng một đối tượng hay không (cùng một con trỏ bộ nhớ).

Nếu bạn đang làm việc với serialiser đối tượng trong Doctrine, bạn cần phải luôn tạo một đối tượng mới của đối tượng để lưu nó.

I.e.

$user = $form->getData(); 

$properties = new UserProperties(); 
$properties->setProperty1($oldValue1); 
$properties->setProperty2($newValue2); 
... 
$user->setProperties($properties); 

$em->persist($properties); 
$em->flush(); 

Tất nhiên bạn có thể tạo bản sao của đối tượng và chỉ gán giá trị đã thay đổi.

$properties = clone $user->getProperties(); 
$properties->setProperty1($newValue); 

$em->persist($properties); 
$em->flush(); 
Các vấn đề liên quan