我有两个实体类,Product
和OrderEntry
,定义如下(为了紧凑而省略了一些注释):
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();
}
}
然而,这引发了一个例外
的异常具有a的实体的单值关联路径表达式 不支持复合主键。明确命名组件 查询中的复合主键。
如何明确命名组件?我知道我可以通过JOIN来做到这一点,但在这种情况下我对产品毫无用处,只会使查询更加昂贵。
答案 0 :(得分: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()
...