我有三个实体,卖家(Vendor),商店(Loja)和特许经营(Franquia),关系描述如下:
1 - 卖家到商店:多对多
2 - 商店到特许经营:多对一
下面是我的 JPQL 查询:
@Query("SELECT v FROM Vendedor v " +
"LEFT JOIN v.lojas l ON l.franquia.voToken = :tokenFranquia AND v.voId = :voId ")
Optional<Vendedor> getByVoIdAndTokenFranquia(Integer voId,String tokenFranquia);
在此查询中,我想获取供应商,其中其 ERP id (voId) 和 tokenFranquia 是某个固定值,上面的查询预计将翻译为如下所示:
SELECT *
FROM vendedores v
LEFT JOIN vendedores_lojas vl ON vl.vendedor_system_id = v.system_id
JOIN lojas l ON l.system_id = vl.loja_system_id
JOIN franquias f ON f.system_id = l.franquia_system_id
WHERE f.vo_token=:param1
AND v.vo_id = :param2
但它被翻译成另一种完全不同且难以辨认的东西:
SELECT (ignoring selected columns because names are too many)
FROM vendedores v1_0
LEFT JOIN
(vendedores_lojas l1_0
JOIN (lojas l1_1
JOIN franquias f1_0
ON f1_0.system_id=l1_1.franquia_system_id)
ON l1_1.system_id=l1_0.loja_system_id)
ON v1_0.system_id=l1_0.vendedor_system_id AND f1_0.vo_token=? AND v1_0.vo_id=?
这让我得到了错误的结果。
问题是:
如何使用 JPQL 获得所需的结果?
@Entity
@Table(name="vendedores")
@Data
@EqualsAndHashCode(of="systemId")
public class Vendedor {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(name="system_id")
private String systemId;
private Integer voId;
private String documento;
private String nome;
private Boolean isDigital;
private Boolean ativo;
@ManyToMany
@JoinTable(
name="vendedores_lojas",
joinColumns = @JoinColumn(name="vendedor_system_id",referencedColumnName = "system_id"),
inverseJoinColumns = @JoinColumn(name="loja_system_id",referencedColumnName = "system_id")
)
@JsonBackReference
private Set<Loja> lojas;
}
@Entity
@Table(name="lojas")
@Data
@EqualsAndHashCode(of="systemId")
public class Loja {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(name="system_id")
private String systemId;
private Integer voId;//not unique
private String nome;
@ManyToOne
@JoinColumn(name="franquia_system_id")
@JsonBackReference
private Franquia franquia;
}
@Entity
@Table(name="franquias")
@Data
@EqualsAndHashCode(of="systemId")
public class Franquia {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String systemId;
private String voToken;
private String cnpj;
private String nome;
private Boolean isMatriz;
}
老实说,我正在考虑放弃 JPQL 查询而只使用本机查询,因为结果总是令人惊讶
问题可能来自连接,我的印象是它没有正确完成。该选择似乎结合了连接和“where”条件。
你能试试这个吗:
@Query("""
SELECT v FROM Vendedor v
LEFT JOIN FETCH v.lojas vl
LEFT JOIN FETCH vl.franquia f
WHERE v.voId = :voId AND f.vo_token = :tokenFranquia
""")
Optional<Vendedor> getByVoIdAndTokenFranquia(Integer voId,String tokenFranquia);