2017-11-22 24 views
10

Tôi đã định cấu hình hai kết nối với cơ sở dữ liệu. Một kết nối được gọi là người dùng và khác được gọi là khách hàng. Đây là cấu hình trong tệp config.yml:Nhiều người quản lý thực thể trong Symfony 3.3 đường nối không hoạt động như đối số dịch vụ

doctrine: 
    dbal: 
     default_connection: client 
     connections: 
      client: 
       driver: pdo_mysql 
       host: '%client_database_host%' 
       port: '%client_database_port%' 
       dbname: '%client_database_name%' 
       user: '%client_database_user%' 
       password: '%client_database_password%' 
       charset: UTF8 
       mapping_types: 
        enum: string 
      user: 
       driver: pdo_mysql 
       host: '%user_database_host%' 
       port: '%user_database_port%' 
       dbname: '%user_database_name%' 
       user: '%user_database_user%' 
       password: '%user_database_password%' 
       charset: UTF8 
       mapping_types: 
        enum: string 

    orm: 
     auto_generate_proxy_classes: '%kernel.debug%' 
     default_entity_manager: ~ 
     entity_managers: 
      client: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        ProjectModelBundle: ~ 
       connection: client 
      user: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        BaseModelBundle: ~ 
        ProjectModelBundle: ~ 
       connection: user 

Nhưng tôi luôn nhận được người quản lý thực thể đầu tiên bất kể điều gì. Đây là cách tôi đang sử dụng dịch vụ của người quản lý thực thể trong các dịch vụ:

# BASE 
    htec.project_model_bundle.repository.database.client_base: 
     class: Project\BaseModelBundle\Repository\Database\DatabaseRepository 
     arguments: ['@service_container', '@doctrine.orm.client_entity_manager', '@form.factory'] 

    htec.project_model_bundle.repository.database.user_base: 
     class: Project\BaseModelBundle\Repository\Database\DatabaseRepository 
     arguments: ['@service_container', '@doctrine.orm.user_entity_manager', '@form.factory'] 

Nhưng bất kể tôi làm gì, tôi luôn nhận được người quản lý thực thể đầu tiên mà tôi đã xác định trong cài đặt orm-> entity_managers. Ví dụ, nếu cấu hình orm như thế này:

orm: 
     auto_generate_proxy_classes: '%kernel.debug%' 
     default_entity_manager: ~ 
     entity_managers: 
      client: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        ProjectModelBundle: ~ 
       connection: client 
      user: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        BaseModelBundle: ~ 
        ProjectModelBundle: ~ 
       connection: user 

tôi sẽ luôn luôn có được người quản lý thực thể khách hàng ngay cả khi tôi cung cấp '@ doctrine.orm.user_entity_manager' như là đối số dịch vụ.

Nếu tôi cấu hình ORM như thế này:

orm: 
     auto_generate_proxy_classes: '%kernel.debug%' 
     default_entity_manager: ~ 
     entity_managers: 
      user: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        BaseModelBundle: ~ 
        ProjectModelBundle: ~ 
       connection: user 
      client: 
       naming_strategy: doctrine.orm.naming_strategy.underscore 
       mappings: 
        ProjectModelBundle: ~ 
       connection: client 

Tôi sẽ luôn luôn nhận được quản lý sử dụng thực thể ngay cả khi tôi cung cấp '@ doctrine.orm.client_entity_manager' như là đối số dịch vụ.

Tôi đang làm gì sai ở đây?

+1

Bạn đã kiểm tra 'bin/console debug : container doctrine.orm.client_entity_manager' (hoặc khác) cho dù các dịch vụ được đăng ký một cách chính xác trong container? – dbrumann

+1

Bạn đã thử sử dụng '@ doctrine' cung cấp cho bạn một [Registry] (https://github.com/doctrine/DoctrineBundle/blob/master/Registry.php) mà bạn có thể sử dụng' getEntityManagerForClass() 'để lấy ra quản lý thực thể đúng cho bất kỳ lớp nào bên trong dịch vụ của bạn? – dbrumann

Trả lời

-1

Vì vậy, bạn đã xác định dịch vụ có tên DatabaseRepository tồn tại trong hai biến thể. Tại một thời điểm, nó nhận được trình quản lý thực thể 'khách hàng' và tại một điểm khác, nó sẽ nhận được trình quản lý thực thể 'người dùng'?

Tôi nghĩ rằng nó luôn luôn trả về cho bạn người quản lý 'khách hàng' có lẽ vì đó là lần đầu tiên dịch vụ được xác định cho vùng chứa dịch vụ. Không quan trọng bạn định nghĩa nó sau đó trong cùng một mã .yml.

Bây giờ, có một câu hỏi hùng biện "tại sao" cho bạn. Tại sao bạn không định nghĩa hai lớp dịch vụ, mỗi lớp cho một người quản lý cụ thể? Nếu bạn thực sự phải làm theo cách đó, điều đó cho thấy một số vấn đề thiết kế nghiêm trọng trong mã còn lại của Dự án của bạn.

Một đề xuất khác: Đặt tên cho các lớp của bạn có phần mô tả hơn. Một người quản lý thực thể và lớp kho lưu trữ chắc chắn làm điều gì đó về một cơ sở dữ liệu. Đặt tên cho các lớp, thuộc tính, biến theo cách thích hợp mà tôi thấy là một phần khó khăn nhất trong công việc, nhưng nó làm cho cuộc sống của chúng ta dễ dàng hơn.

Btw. Tránh chuyển toàn bộ vùng chứa làm thông số dịch vụ:

arguments: ['@service_container', 

vì tài nguyên quá đắt tiền khôn ngoan.

0

Gần đây tôi gặp sự cố tương tự. Nhận xét của @dbrumann đã cho tôi một đầu mối tốt để giải quyết nó. Tôi đã sử dụng cách tiếp cận tiếp theo:

  1. Nếu bạn sử dụng lệnh console debug:autowiring bạn sẽ thấy có một dịch vụ được đặt bí danh là học thuyết.

    Doctrine\Common\Persistence\ManagerRegistry alias to doctrine 
    
  2. Bạn có thể nhận được quyền truy cập vào dịch vụ đó trong lớp mục tiêu của bạn theo loại-gián tiếp, đặt tên của lớp dịch vụ (hoặc giao diện) như là đối số trong constructor của lớp mục tiêu của bạn.

  3. Bây giờ bạn có thể truy cập tất cả các phương pháp của dịch vụ trong lớp mục tiêu của bạn, bằng cách sử dụng phương pháp này getManager() bạn sẽ nhận được bất kỳ cán bộ quản lý của bạn:

    use Doctrine\Common\Persistence\ManagerRegistry; 
    
    $protected $managerRegistry; 
    
    public function __construct(ManagerRegistry $managerRegistry) 
    { 
        $this->managerRegistry = $managerRegistry; 
    } 
    
    public function foo() 
    { 
        // asuming your managers names are default and second 
        $firstManager = $this->managerRegistry->getManager('default'); 
        $secondManager = $this->managerRegistry->getManager('second'); 
    } 
    
Các vấn đề liên quan