2012-02-21 22 views
9

tôi muốn lưu một trong những thực thể của tôi đối tượng vào phiên giao dịch, nhưng như tôi đang làm như vậy, tôi nhận được hai lỗi sau đây:Symfony2 serialize thực thể đối tượng để phiên

Ngoại lệ: Symfony \ Bundle \ FrameworkBundle \ DataCollector \ RequestDataCollector :: serialize() phải trả lại một chuỗi hoặc NULL

ErrorException: Thông báo: nối tiếp ize(): "id" được trả về thành viên biến từ __sleep() nhưng không tồn tại trong /var/www/clients/client71/web256/web/_dev_fd/kkupon/vendor/symfony/src/Symfony/Component/HttpKernel /DataCollector/DataCollector.php dòng 29

mã của tôi đi như thế này:

$offer = $this->getEntityManager()->getRepository('KkuponMainBundle:Offer')->find($offer_id); 
$request->getSession()->set('offer', $offer); 

Làm sao tôi nhận được nó phải không?

Cảm ơn bạn.

CẬP NHẬT Với sự trợ giúp của Rowgm tôi có thể khắc phục sự cố này bằng cách đặt thuộc tính được bảo vệ thay vì riêng tư. Vấn đề duy nhất tôi gặp phải là sau khi đọc thực thể từ phiên mà EntityManager không biết về nó và nếu tôi thêm đối tượng (từ phiên) vào đối tượng khác (có mối quan hệ OneToMany giữa chúng), nó sẽ không công việc.

<?php 
$offer = $this->get('session')->get('offer'); 
$coupon = new Coupon(); 
$coupon->setOffer($offer); 
$this->em->persist($coupon); 
$this->em->flush(); 

Điều này đặt ra một lỗi, vì phiếu giảm giá có một tài sản đối tượng mà theo EntityManager không có trong cơ sở dữ liệu (trên thực tế nó là trong DB, tôi đưa vào phiên giao dịch từ DB).

<?php 
$offer = $this->get('session')->get('offer'); 
echo $this->em->getUnitOfWork()->isInIdentityMap($offer) ? "yes":"no"; //result: no 

Một giải pháp có thể là: $offer = $this->em->merge($offer);

Nhưng điều này không có vẻ là tốt nhất. Tôi muốn EntityManager của tôi để cảm nhận các đối tượng thực thể được lưu trữ trong phiên mà không nói với nó mỗi lần. Bất kỳ ý tưởng nào?

Trả lời

14

Bạn có thể sắp xếp bất kỳ thực thể nào bằng cách đặt tất cả các thuộc tính và mối quan hệ của chúng từ riêng thành được bảo vệ.

Bạn có thể gặp sự cố thường gặp với symfony2, ngay cả khi bạn đã đặt tất cả các thuộc tính thành được bảo vệ: Bạn phải tạo lại proxy của các thực thể bạn đã thay đổi. Để làm như vậy, chỉ cần xóa bộ nhớ cache.Đối với dev môi trường:

app/console cache:clear

Nó hoạt động ngay cả khi "nó chứa nhiều đối tượng nước ngoài và thậm chí ArrayCollections của các tổ chức nước ngoài" như bạn nói.

+0

Cảm ơn bạn, nó đã giúp rất nhiều. –

+0

Xin vui lòng, nếu bạn có thể, hãy trả lời phần cập nhật của câu hỏi của tôi. –

+0

Hãy suy nghĩ về nó: Nếu bạn lưu trữ tất cả các thực thể đó, bạn sẽ lưu trữ một đối tượng lớn trong dữ liệu phiên của bạn. Đối với môi trường develepment của bạn, nó không phải là một vấn đề. Nhưng nếu bạn có nhiều người dùng, nó là một sự lãng phí tài nguyên. Giải pháp rất đơn giản: lưu trữ id của đối tượng và sử dụng phương thức find() của kho lưu trữ để truy lục đối tượng. Cuối cùng, đó là điều tương tự. –

6

Thực thể tuần tự không được khuyến nghị, như bạn có thể thấy trong Doctrine-documentation. Bạn nên triển khai Serializable-interface và tuần tự hóa/deserialize dữ liệu thực thể theo cách thủ công.

+0

Serializing thực thể của tôi sẽ là vấn đề vì nó có chứa nhiều đối tượng nước ngoài và thậm chí ArrayCollections của các tổ chức nước ngoài. Bất kỳ ý tưởng tốt hơn so với chỉ lưu trữ các id và lấy đối tượng từ cơ sở dữ liệu mỗi khi tôi cần nó? –

+0

Như bạn có thể thấy từ ngoại lệ của bạn, khi đưa nó vào một phiên, nó sẽ được đăng, đó là nguyên nhân gây ra lỗi. Nhưng như bạn nói, do sự phức tạp của đối tượng của bạn, bạn có lẽ nên đi với lưu trữ các id và lấy các đối tượng từ cơ sở dữ liệu một lần nữa. Có thể sử dụng một số loại đối tượng bộ nhớ cache có thể làm việc là tốt, nhưng tôi không chắc chắn. – dbrumann

+1

Cảm ơn bạn, tôi sẽ chỉ lưu trữ id. –

2

Bạn có thể loại trừ các lĩnh vực unnesseary bởi overridding __sleep phương pháp:

public function __sleep() { 

    // these are field names to be serialized, others will be excluded 
    // but note that you have to fill other field values by your own 
    return array('id', 'username', 'password', 'salt'); 
} 
Các vấn đề liên quan