2

我有两个实体类ProductOrderEntry,定义如下(为了紧凑而省略了一些注释):

class Product {

   /**
    * @Id
    */
   protected $id;

   /**
    * @Column()
    * @Id
    */
   protected $prodNumber;

   /**
    * @Column()
    * @Id
    */
   protected $group;

   // more cols here
}

class OrderEntry {

   // more cols here

   /**
    * @ManyToOne(targetEntity="Product")
    * @JoinColumns({
    *      @JoinColumn(name="prodNumber", referencedColumnName="prodNumber"),
    *      @JoinColumn(name="group", referencedColumnName="group")
    * })
    */
   protected $Product;
}

现在我想通过与查询生成器关联的 Product 来查找 OrderEntry。对我来说最合乎逻辑的事情是:

class OrderEntryRepository extends EntityRepository  {

    public function findByProduct($product) {
       $qb = $this->getQueryBuilder('o');
       $qb->where($qb->expr()->eq('o.Product', '?1')
          ->setParameter(1, $product)
          ->setMaxResults(1);
       return $qb->getQuery()->execute(); 
    }
}

但是,这会引发一个异常,说明

不支持到具有复合主键的实体的单值关联路径表达式。在查询中显式命名复合主键的组件。

如何明确命名组件?我知道我可以通过 JOIN 来做到这一点,但在这种情况下我对 Product 没有用处,它只会使查询变得更加昂贵。

4

1 回答 1

1

您无法避免使用当前映射加入 products 表:

public function findByProduct($product) {
   $qb = $this->getQueryBuilder('o');
   $qb
      ->join('o.Product', 'p')
      ->where('p.prodNumber = ?1')
      ->setParameter(1, $product->getProdNumber())
      ->andWhere('p.group = ?2')
      ->setParameter(2, $product->getGroup())
   ;
   return $qb->getQuery()->getOneOrNullResult(); 
}

您可以向 OrderEntry 添加单独的属性,这将使用与 JoinColumns 相同的列,例如:

/**
 * @Column(name="prodNumber")
 */
protected $prodNumber;

然后你可以在条件下使用它们:

... 
->where('o.prodNumber = ?1')
->setParameter(1, $product->getProdNumber()
...
于 2012-04-21T09:32:56.323 回答