JpaRepository 返回一个包含重复对象的列表

4

我正在尝试找出如何从JPA存储库中正确获取2个对象

现在这是我的存储库:

@Transactional
public interface CompanyDao extends JpaRepository<Company, Integer> {
    //HQL query
    @Query("SELECT e,b from EstimateOptions e,BillNumber b inner join e.Company company inner join company.user user where user.email = :userName\n")
    List <Object[]>testQuery(@Param("userName") String userName);
}

但是当我在控制器内进行测试时

@RequestMapping(value = "/getcompanyestimateoptions")
public List getCompanyEstimateOptions(@AuthenticationPrincipal Principal user) {



    LOGGER.info("TEST LIST");
    List<Object[]> listObjects = companyDao.testQuery(user.getName());

    for (Object object[] : listObjects) {
        EstimateOptions estimateOptions = (EstimateOptions) object[0];
        BillNumber billNumber = (BillNumber) object[1];

        LOGGER.info(estimateOptions.toString());
        LOGGER.info(billNumber.toString());
        LOGGER.info(object.toString());
    }

    LOGGER.info("START ESTIMATEOPTIONS QUERY");


    return listObjects;

}

实体用户
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_user")
    private Integer id;

    @OneToOne( cascade = CascadeType.ALL)
    @JoinColumn(name = "fkIdCompanyUser")
    private Company company = new Company();
}

实体账单编号

@Entity
@Table(name ="tbl_BillNumber")
public class BillNumber {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(UserController.class);


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_BillNumber")
    private Integer id;
}

实体类 EstimateOptions

@Entity
@Table(name ="tbl_Estimateoptions")
public class EstimateOptions {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(EstimateOptions.class);


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_Estimateoptions")
    private Integer id;
}

实体公司

@Entity
@Table(name ="tbl_Company")
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_company")
    private Integer id;

    @OneToOne(mappedBy="company", fetch = FetchType.LAZY)
    private User user;

    @OneToOne( cascade = CascadeType.ALL)
    @JoinColumn(name = "fkIdCompanyBill")
    private BillNumber billnumber = new BillNumber();

    @OneToOne( cascade = CascadeType.ALL)
    @JoinColumn(name = "fkIdCompanyEstimateOption")
    private EstimateOptions estimateOptions = new EstimateOptions();
}

这是 SQL 的输出结果:

Hibernate: select distinct estimateop0_.id_estimateoptions as id_estim1_6_0_, billnumber1_.id_bill_number as id_bill_1_0_1_, estimateop0_.estimate_customer_note as estimate2_6_0_, estimateop0_.estimate_model as estimate3_6_0_, estimateop0_.estimate_model_primary_color as estimate4_6_0_, estimateop0_.estimate_model_secondary_color as estimate5_6_0_, estimateop0_.estimate_model_tertiary_color as estimate6_6_0_, estimateop0_.estimate_personal_note as estimate7_6_0_, estimateop0_.estimate_terms as estimate8_6_0_, billnumber1_.credit_note_numberprefix as credit_n2_0_1_, billnumber1_.credit_note_numbersuffix as credit_n3_0_1_, billnumber1_.credit_note_start_number as credit_n4_0_1_, billnumber1_.customers_id_on as customer5_0_1_, billnumber1_.estimate_numberprefix as estimate6_0_1_, billnumber1_.estimate_numbersuffix as estimate7_0_1_, billnumber1_.estimate_start_number as estimate8_0_1_, billnumber1_.every_year_new_date_on as every_ye9_0_1_, billnumber1_.invoice_numberprefix as invoice10_0_1_, billnumber1_.invoice_numbersuffix as invoice11_0_1_, billnumber1_.invoice_project_number as invoice12_0_1_, billnumber1_.invoice_start_number as invoice13_0_1_, billnumber1_.month_on as month_o14_0_1_, billnumber1_.project_number_numberprefix as project15_0_1_, billnumber1_.project_number_on as project16_0_1_, billnumber1_.project_number_total_prefix_numbers as project17_0_1_, billnumber1_.total_prefix_numbers as total_p18_0_1_, billnumber1_.year_on as year_on19_0_1_ from tbl_estimateoptions estimateop0_ inner join tbl_company company2_ on estimateop0_.id_estimateoptions=company2_.fk_id_company_estimate_option inner join tbl_user user3_ on company2_.id_company=user3_.fk_id_company_user cross join tbl_bill_number billnumber1_ where user3_.email=?
Hibernate: select company0_.id_company as id_compa1_2_2_, company0_.bank_account as bank_acc2_2_2_, company0_.fk_id_company_bill as fk_id_c18_2_2_, company0_.city as city3_2_2_, company0_.company_name as company_4_2_2_, company0_.contact_email as contact_5_2_2_, company0_.contact_telephone as contact_6_2_2_, company0_.country as country7_2_2_, company0_.dateformat as dateform8_2_2_, company0_.default_currency as default_9_2_2_, company0_.fk_id_company_estimate_option as fk_id_c19_2_2_, company0_.hide_tax_number_on_estimate as hide_ta10_2_2_, company0_.house_number as house_n11_2_2_, company0_.street as street12_2_2_, company0_.tax_number as tax_num13_2_2_, company0_.tax_number_enabled as tax_num14_2_2_, company0_.website as website15_2_2_, company0_.website_enabled as website16_2_2_, company0_.zip_code as zip_cod17_2_2_, billnumber1_.id_bill_number as id_bill_1_0_0_, billnumber1_.credit_note_numberprefix as credit_n2_0_0_, billnumber1_.credit_note_numbersuffix as credit_n3_0_0_, billnumber1_.credit_note_start_number as credit_n4_0_0_, billnumber1_.customers_id_on as customer5_0_0_, billnumber1_.estimate_numberprefix as estimate6_0_0_, billnumber1_.estimate_numbersuffix as estimate7_0_0_, billnumber1_.estimate_start_number as estimate8_0_0_, billnumber1_.every_year_new_date_on as every_ye9_0_0_, billnumber1_.invoice_numberprefix as invoice10_0_0_, billnumber1_.invoice_numbersuffix as invoice11_0_0_, billnumber1_.invoice_project_number as invoice12_0_0_, billnumber1_.invoice_start_number as invoice13_0_0_, billnumber1_.month_on as month_o14_0_0_, billnumber1_.project_number_numberprefix as project15_0_0_, billnumber1_.project_number_on as project16_0_0_, billnumber1_.project_number_total_prefix_numbers as project17_0_0_, billnumber1_.total_prefix_numbers as total_p18_0_0_, billnumber1_.year_on as year_on19_0_0_, estimateop2_.id_estimateoptions as id_estim1_6_1_, estimateop2_.estimate_customer_note as estimate2_6_1_, estimateop2_.estimate_model as estimate3_6_1_, estimateop2_.estimate_model_primary_color as estimate4_6_1_, estimateop2_.estimate_model_secondary_color as estimate5_6_1_, estimateop2_.estimate_model_tertiary_color as estimate6_6_1_, estimateop2_.estimate_personal_note as estimate7_6_1_, estimateop2_.estimate_terms as estimate8_6_1_ from tbl_company company0_ left outer join tbl_bill_number billnumber1_ on company0_.fk_id_company_bill=billnumber1_.id_bill_number left outer join tbl_estimateoptions estimateop2_ on company0_.fk_id_company_estimate_option=estimateop2_.id_estimateoptions where company0_.fk_id_company_estimate_option=?
Hibernate: select user0_.id_user as id_user1_9_3_, user0_.authority as authorit2_9_3_, user0_.fk_id_company_user as fk_id_co8_9_3_, user0_.email as email3_9_3_, user0_.enabled as enabled4_9_3_, user0_.first_name as first_na5_9_3_, user0_.last_name as last_nam6_9_3_, user0_.password as password7_9_3_, company1_.id_company as id_compa1_2_0_, company1_.bank_account as bank_acc2_2_0_, company1_.fk_id_company_bill as 

列表中包含两个 BillNumberEstimateOptions。因此,当我将其发送到前端时,我会得到一个带有 2 个重复信息的数组。我做错了什么? 编辑 在使用以下查询时:
@Query("SELECT distinct  e,b from EstimateOptions e,BillNumber b join fetch e.Company company join fetch company.user user where user.email = :userName\n")
List <Object[]>testQuery(@Param("userName") String userName);

现在的SQL输出为:

 Hibernate: select distinct estimateop0_.id_estimateoptions as id_estim1_6_0_, billnumber1_.id_bill_number as id_bill_1_0_1_, company2_.id_company as id_compa1_2_2_, user3_.id_user as id_user1_9_3_, estimateop0_.estimate_customer_note as estimate2_6_0_, estimateop0_.estimate_model as estimate3_6_0_, estimateop0_.estimate_model_primary_color as estimate4_6_0_, estimateop0_.estimate_model_secondary_color as estimate5_6_0_, estimateop0_.estimate_model_tertiary_color as estimate6_6_0_, estimateop0_.estimate_personal_note as estimate7_6_0_, estimateop0_.estimate_terms as estimate8_6_0_, billnumber1_.credit_note_numberprefix as credit_n2_0_1_, billnumber1_.credit_note_numbersuffix as credit_n3_0_1_, billnumber1_.credit_note_start_number as credit_n4_0_1_, billnumber1_.customers_id_on as customer5_0_1_, billnumber1_.estimate_numberprefix as estimate6_0_1_, billnumber1_.estimate_numbersuffix as estimate7_0_1_, billnumber1_.estimate_start_number as estimate8_0_1_, billnumber1_.every_year_new_date_on as every_ye9_0_1_, billnumber1_.invoice_numberprefix as invoice10_0_1_, billnumber1_.invoice_numbersuffix as invoice11_0_1_, billnumber1_.invoice_project_number as invoice12_0_1_, billnumber1_.invoice_start_number as invoice13_0_1_, billnumber1_.month_on as month_o14_0_1_, billnumber1_.project_number_numberprefix as project15_0_1_, billnumber1_.project_number_on as project16_0_1_, billnumber1_.project_number_total_prefix_numbers as project17_0_1_, billnumber1_.total_prefix_numbers as total_p18_0_1_, billnumber1_.year_on as year_on19_0_1_, company2_.bank_account as bank_acc2_2_2_, company2_.fk_id_company_bill as fk_id_c18_2_2_, company2_.city as city3_2_2_, company2_.company_name as company_4_2_2_, company2_.contact_email as contact_5_2_2_, company2_.contact_telephone as contact_6_2_2_, company2_.country as country7_2_2_, company2_.dateformat as dateform8_2_2_, company2_.default_currency as default_9_2_2_, company2_.fk_id_company_estimate_option as fk_id_c19_2_2_, company2_.hide_tax_number_on_estimate as hide_ta10_2_2_, company2_.house_number as house_n11_2_2_, company2_.street as street12_2_2_, company2_.tax_number as tax_num13_2_2_, company2_.tax_number_enabled as tax_num14_2_2_, company2_.website as website15_2_2_, company2_.website_enabled as website16_2_2_, company2_.zip_code as zip_cod17_2_2_, user3_.authority as authorit2_9_3_, user3_.fk_id_company_user as fk_id_co8_9_3_, user3_.email as email3_9_3_, user3_.enabled as enabled4_9_3_, user3_.first_name as first_na5_9_3_, user3_.last_name as last_nam6_9_3_, user3_.password as password7_9_3_ from tbl_estimateoptions estimateop0_ inner join tbl_company company2_ on estimateop0_.id_estimateoptions=company2_.fk_id_company_estimate_option inner join tbl_user user3_ on company2_.id_company=user3_.fk_id_company_user cross join tbl_bill_number billnumber1_ where user3_.email=?

但是这份清单仍然包含重复的信息。

我也看不出 e 和 b 之间有任何关系,所以它可能会将任何 b 加入到所选的 e 中。这可能不是您当前面临的问题,但很可能会在未来引起一些问题。 - Thomas
我也添加了我的实体。有什么线索我做错了吗? - Greg
@Simo 我的实体类中没有任何等于或哈希码。 - Greg
@Simo 我确实会得到一些对象两次。 - Greg
请尝试以下查询: @Query("SELECT company from Company company where company.user.email = :userName\n") List <Company>testQuery(@Param("userName") String userName);以及getCompanyEstimateOptions方法:List<Company> listObjects = companyDao.testQuery(user.getName());for (Company c : listObjects) { EstimateOptions estimateOptions = c.getEstimateOptions(); BillNumber billNumber = c.getBillNumber(); .... - Si mo
显示剩余12条评论
1个回答

1
我找到了一个可能的解决方案。最后,我像这样重新配置了查询。现在我得到了一个带有EstimateOptions和BillNumber的对象,而不是所有公司或用户设置。也没有重复的对象了。
@Query("from EstimateOptions options,BillNumber billnumber join fetch billnumber.Company company2 join fetch company2.user user2  join fetch options.Company company join fetch company.user user where user.email = :userName and user2.email = :userName")
Set<Object[]> testQuery6(@Param("userName") String userName);

但是我的查询中仍然有一些重复的信息。
Hibernate: select estimateop0_.id_estimateoptions as id_estim1_6_0_, company4_.id_company as id_compa1_2_1_, user5_.id_user as id_user1_9_2_, billnumber1_.id_bill_number as id_bill_1_0_3_, company2_.id_company as id_compa1_2_4_, user3_.id_user as id_user1_9_5_, estimateop0_.estimate_customer_note as estimate2_6_0_, estimateop0_.estimate_model as estimate3_6_0_, estimateop0_.estimate_model_primary_color as estimate4_6_0_, estimateop0_.estimate_model_secondary_color as estimate5_6_0_, estimateop0_.estimate_model_tertiary_color as estimate6_6_0_, estimateop0_.estimate_personal_note as estimate7_6_0_, estimateop0_.estimate_terms as estimate8_6_0_, company4_.bank_account as bank_acc2_2_1_, company4_.fk_id_company_bill as fk_id_c18_2_1_, company4_.city as city3_2_1_, company4_.company_name as company_4_2_1_, company4_.contact_email as contact_5_2_1_, company4_.contact_telephone as contact_6_2_1_, company4_.country as country7_2_1_, company4_.dateformat as dateform8_2_1_, company4_.default_currency as default_9_2_1_, company4_.fk_id_company_estimate_option as fk_id_c19_2_1_, company4_.hide_tax_number_on_estimate as hide_ta10_2_1_, company4_.house_number as house_n11_2_1_, company4_.street as street12_2_1_, company4_.tax_number as tax_num13_2_1_, company4_.tax_number_enabled as tax_num14_2_1_, company4_.website as website15_2_1_, company4_.website_enabled as website16_2_1_, company4_.zip_code as zip_cod17_2_1_, user5_.authority as authorit2_9_2_, user5_.fk_id_company_user as fk_id_co8_9_2_, user5_.email as email3_9_2_, user5_.enabled as enabled4_9_2_, user5_.first_name as first_na5_9_2_, user5_.last_name as last_nam6_9_2_, user5_.password as password7_9_2_, billnumber1_.credit_note_numberprefix as credit_n2_0_3_, billnumber1_.credit_note_numbersuffix as credit_n3_0_3_, billnumber1_.credit_note_start_number as credit_n4_0_3_, billnumber1_.customers_id_on as customer5_0_3_, billnumber1_.estimate_numberprefix as estimate6_0_3_, billnumber1_.estimate_numbersuffix as estimate7_0_3_, billnumber1_.estimate_start_number as estimate8_0_3_, billnumber1_.every_year_new_date_on as every_ye9_0_3_, billnumber1_.invoice_numberprefix as invoice10_0_3_, billnumber1_.invoice_numbersuffix as invoice11_0_3_, billnumber1_.invoice_project_number as invoice12_0_3_, billnumber1_.invoice_start_number as invoice13_0_3_, billnumber1_.month_on as month_o14_0_3_, billnumber1_.project_number_numberprefix as project15_0_3_, billnumber1_.project_number_on as project16_0_3_, billnumber1_.project_number_total_prefix_numbers as project17_0_3_, billnumber1_.total_prefix_numbers as total_p18_0_3_, billnumber1_.year_on as year_on19_0_3_, company2_.bank_account as bank_acc2_2_4_, company2_.fk_id_company_bill as fk_id_c18_2_4_, company2_.city as city3_2_4_, company2_.company_name as company_4_2_4_, company2_.contact_email as contact_5_2_4_, company2_.contact_telephone as contact_6_2_4_, company2_.country as country7_2_4_, company2_.dateformat as dateform8_2_4_, company2_.default_currency as default_9_2_4_, company2_.fk_id_company_estimate_option as fk_id_c19_2_4_, company2_.hide_tax_number_on_estimate as hide_ta10_2_4_, company2_.house_number as house_n11_2_4_, company2_.street as street12_2_4_, company2_.tax_number as tax_num13_2_4_, company2_.tax_number_enabled as tax_num14_2_4_, company2_.website as website15_2_4_, company2_.website_enabled as website16_2_4_, company2_.zip_code as zip_cod17_2_4_, user3_.authority as authorit2_9_5_, user3_.fk_id_company_user as fk_id_co8_9_5_, user3_.email as email3_9_5_, user3_.enabled as enabled4_9_5_, user3_.first_name as first_na5_9_5_, user3_.last_name as last_nam6_9_5_, user3_.password as password7_9_5_ from tbl_estimateoptions estimateop0_ inner join tbl_company company4_ on estimateop0_.id_estimateoptions=company4_.fk_id_company_estimate_option inner join tbl_user user5_ on company4_.id_company=user5_.fk_id_company_user cross join tbl_bill_number billnumber1_ inner join tbl_company company2_ on billnumber1_.id_bill_number=company2_.fk_id_company_bill inner join tbl_user user3_ on company2_.id_company=user3_.fk_id_company_user where user5_.email=? and user3_.email=?
Hibernate: select company0_.id_company as id_compa1_2_2_, company0_.bank_account as bank_acc2_2_2_, company0_.fk_id_company_bill as fk_id_c18_2_2_, company0_.city as city3_2_2_, company0_.company_name as company_4_2_2_, company0_.contact_email as contact_5_2_2_, company0_.contact_telephone as contact_6_2_2_, company0_.country as country7_2_2_, company0_.dateformat as dateform8_2_2_, company0_.default_currency as default_9_2_2_, company0_.fk_id_company_estimate_option as fk_id_c19_2_2_, company0_.hide_tax_number_on_estimate as hide_ta10_2_2_, company0_.house_number as house_n11_2_2_, company0_.street as street12_2_2_, company0_.tax_number as tax_num13_2_2_, company0_.tax_number_enabled as tax_num14_2_2_, company0_.website as website15_2_2_, company0_.website_enabled as website16_2_2_, company0_.zip_code as zip_cod17_2_2_, billnumber1_.id_bill_number as id_bill_1_0_0_, billnumber1_.credit_note_numberprefix as credit_n2_0_0_, billnumber1_.credit_note_numbersuffix as credit_n3_0_0_, billnumber1_.credit_note_start_number as credit_n4_0_0_, billnumber1_.customers_id_on as customer5_0_0_, billnumber1_.estimate_numberprefix as estimate6_0_0_, billnumber1_.estimate_numbersuffix as estimate7_0_0_, billnumber1_.estimate_start_number as estimate8_0_0_, billnumber1_.every_year_new_date_on as every_ye9_0_0_, billnumber1_.invoice_numberprefix as invoice10_0_0_, billnumber1_.invoice_numbersuffix as invoice11_0_0_, billnumber1_.invoice_project_number as invoice12_0_0_, billnumber1_.invoice_start_number as invoice13_0_0_, billnumber1_.month_on as month_o14_0_0_, billnumber1_.project_number_numberprefix as project15_0_0_, billnumber1_.project_number_on as project16_0_0_, billnumber1_.project_number_total_prefix_numbers as project17_0_0_, billnumber1_.total_prefix_numbers as total_p18_0_0_, billnumber1_.year_on as year_on19_0_0_, estimateop2_.id_estimateoptions as id_estim1_6_1_, estimateop2_.estimate_customer_note as estimate2_6_1_, estimateop2_.estimate_model as estimate3_6_1_, estimateop2_.estimate_model_primary_color as estimate4_6_1_, estimateop2_.estimate_model_secondary_color as estimate5_6_1_, estimateop2_.estimate_model_tertiary_color as estimate6_6_1_, estimateop2_.estimate_personal_note as estimate7_6_1_, estimateop2_.estimate_terms as estimate8_6_1_ from tbl_company company0_ left outer join tbl_bill_number billnumber1_ on company0_.fk_id_company_bill=billnumber1_.id_bill_number left outer join tbl_estimateoptions estimateop2_ on company0_.fk_id_company_estimate_option=estimateop2_.id_estimateoptions where company0_.fk_id_company_bill=?

我不会接受我的答案,因为可能有更好的解决方法。但这更像是一个临时解决方案。欢迎留下评论以进一步改进。


也许问题出在生成的查询中的交叉连接上。'CROSS JOIN是一种JOIN操作,它产生两个表的笛卡尔积。与其他JOIN运算符不同,它不允许您指定JOIN子句。但是,您可以在SELECT语句中指定WHERE子句。' - anna
如果使用以下代码,会得到什么结果? select company.estimateOptions, company.billnumber from Company company join fetch company.user user where user.email = :userName.它会工作吗? - anna
@anna 很抱歉回复晚了,但我重新设计了整个实体结构,我认为你是对的,这可能是最好的解决方案。 - Greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接