TypeORM一对多与多对一关联问题:SQL查询生成错误
问题根源
你在CategoryTypeAttribute实体中错误地将categoryTypeId标记为@PrimaryColumn,导致它和id共同构成了复合主键。TypeORM在处理关联关系时,会默认使用实体的所有主键字段生成JOIN条件,因此才会出现错误的关联逻辑——用category_type_attribute.category_type_id去匹配item_attribute.category_type_attribute_id,而不是预期的category_type_attribute.id。
解决方案
1. 修正实体主键配置
修改CategoryTypeAttribute实体,将categoryTypeId的@PrimaryColumn改为普通@Column,只保留id作为唯一主键:
@Entity('category_type_attribute') export class CategoryTypeAttribute { @PrimaryColumn('uuid', { unique: true, nullable: false, comment: 'Unique identifier for the category type attribute', }) @Generated('uuid') id: string; // 将@PrimaryColumn改为@Column @Column({ name: 'category_type_id', comment: 'Id of the associated category type', length: 36, }) categoryTypeId: string; // 其余代码保持不变... }
2. 验证查询
修正实体后,你原来的查询构建器代码无需修改,TypeORM会自动生成正确的JOIN条件:
const categoryTypeAttributes = await dataSource .getRepository(CategoryTypeAttribute) .createQueryBuilder('category_type_attribute') .select([ 'category_type_attribute.id', 'category_type_attribute.name', 'item_attribute.value', ]) .leftJoin( 'category_type_attribute.itemAttributes', 'item_attribute' ) .getMany();
此时生成的SQL会使用item_attribute.category_type_attribute_id = category_type_attribute.id作为关联条件,和你预期的一致。
额外说明
如果你的业务逻辑确实需要CategoryTypeAttribute使用复合主键(id + categoryTypeId),则需要在关联时显式指定JOIN条件,示例如下:
const categoryTypeAttributes = await dataSource .getRepository(CategoryTypeAttribute) .createQueryBuilder('category_type_attribute') .select([ 'category_type_attribute.id', 'category_type_attribute.name', 'item_attribute.value', ]) .leftJoin(ItemAttribute, 'item_attribute', 'item_attribute.category_type_attribute_id = category_type_attribute.id' ) .getMany();
但从你的业务场景来看,id已经是全局唯一的UUID,完全不需要复合主键,所以优先采用第一种方案。
内容的提问来源于stack exchange,提问作者mauri
相关产品推荐
相关产品推荐

