spring数据jpa查询创建了无效的sql

zdwk9cvp  于 2021-06-24  发布在  Mysql
关注(0)|答案(2)|浏览(269)

我尝试使用jpa查询和投影来检索数据的特定部分。以下是查询:

@Repository
public interface CompanyRepository extends CrudRepository<Company, Integer> {
    @Query("select co.companyID as companyid, co.companyName as companyname, co.companyAbbr as companyabbr, co.flags as flags from Company co order by companyName asc")
    List<CompanyWithFlags> getAllCompaniesWithFlags();
}

这是投影图:

public interface CompanyWithFlags {
    Integer getCompanyid();
    String getCompanyname();
    String getCompanyabbr();
    List<CompanyFlag> getFlags();
}

以下是公司实体:

@Entity
@Table(name="companies.companies")
public class Company implements Serializable {
    private static final long serialVersionUID = 1L;

    private int companyID;
    private String companyName;
    private String companyAbbr;
    ...
    private List<CompanyFlag> flags = new ArrayList<>();

    public Company() {}

    @Id
    @Column(name="pk_companyid")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView(View.AllCompaniesView.class)
    public int getCompanyID() {
        return companyID;
    }

    public void setCompanyID(int companyID) {
        this.companyID = companyID;
    }

    @Column(name="companyname", columnDefinition="VARCHAR(72)")
    @JsonView(View.AllCompaniesView.class)
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    @Column(name="companyabbr", columnDefinition="VARCHAR(8)")
    @JsonView(View.AllCompaniesView.class)
    public String getCompanyAbbr() {
        return companyAbbr;
    }

    public void setCompanyAbbr(String companyAbbr) {
        this.companyAbbr = companyAbbr;
    }

    ...

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="companies.co_flags",
               joinColumns = @JoinColumn(name="fk_companyid", referencedColumnName="pk_companyid"),
               inverseJoinColumns = @JoinColumn(name="fk_flagid", referencedColumnName="pk_flagid"))
    @JsonView(View.AllCompaniesView.class)
    public List<CompanyFlag> getFlags() {
        return flags;
    }

    public void setFlags(List<CompanyFlag> flags) {
        this.flags = flags;
    }
}

如果我离开 CompanyFlag 通过查询和投影,一切正常。如果我不编写查询,而是使用:

List<CompanyWithFlags> findAllByOrderByCompanyNameAsc();

然后我得到了所需的数据,但是也生成了一个很长的其他(不必要的)查询列表。
实际上,hibernate(5.2.14)生成以下查询:

select 
  company0_.pk_companyid as col_0_0_, 
  company0_.companyname as col_1_0_, 
  company0_.companyabbr as col_2_0_, 
  . as col_3_0_, 
  companyfla2_.pk_flagid as pk_flagi1_9_, 
  companyfla2_.fk_categoryid as fk_categ3_9_, 
  companyfla2_.flagname as flagname2_9_ 
from companies.companies company0_ 
inner join companies.co_flags flags1_ on company0_.pk_companyid=flags1_.fk_companyid 
inner join companies.config_flags companyfla2_ on flags1_.fk_flagid=companyfla2_.pk_flagid 
order by companyName asc

显然,问题是 . as col_3_0_ ,但我不知道为什么会产生这种情况,也不知道如何消除它。有人能解释一下hibernate为什么要添加它,以及我可以在存储库中做些什么来高效地获得所需的数据吗?谢谢!

xpcnnkqh

xpcnnkqh1#

这看起来像是SpringDataJPA中的一个bug——参见我的报告:datajpa-1299。
要解决此问题,请尝试使用具有“distinct”的查询方法,如下所示:

@EntityGraph(attributePaths = "flags")
List<CompanyWithFlags> findDistinctAllByOrderByCompanyNameAsc();
slsn1g29

slsn1g292#

我终于找到了一个有效的查询,尽管和我预想的不太一样。以下是查询:

@Query("select co.companyID as companyid, co.companyName as companyname, co.companyAbbr as companyabbr, fl as flags from Company co left join co.flags fl order by companyName asc")
List<CompanyWithFlags> getAllCompaniesWithFlags();

我想要的结果是:

companyid: 1,
companyabbr: "ABC",
companyname: "Alpha Beta Company",
flags: [
  {
    flagID: 1,
    flagName: "Flag 1"
  },
  {
    flagID: 2,
    flagName: "Flag 2"
  }
]

但是,查询会产生如下结果:

companyid: 1,
companyabbr: "ABC",
companyname: "Alpha Beta Company",
flags: [
  {
    flagID: 1,
    flagName: "Flag 1"
  }
],
companyid: 1,
companyabbr: "ABC",
companyname: "Alpha Beta Company",
flags: [
  {
    flagID: 2,
    flagName: "Flag 2"
  }
]

我在前端使用angular,它能够正确地读取这些信息以获得我想要的最终结果,所以这个查询对我来说是有效的。它在hibernate中生成最少的sql查询。

相关问题