Hibernate 的 Criteria With Example 和 Query Return 不同的结果

Hibernate's Criteria With Example And Query Return different results

我在应用程序中使用 hibernate 进行实体持久化,但是当我使用 HQL 获取实体时它工作正常并且 returns 是 table 中存在的实体的确切数量但是当我使用 hibernate 的标准和示例它 return 第一个实体两次,因此导致 returning 一个实体多于 table

中实际存在的实体

实体定义

public class ItemParentCategory {

@Id
@GeneratedValue
private long id;

private String name;

@OneToMany(mappedBy = "itemParentCategory",fetch = FetchType.EAGER)
@JsonIgnore
private List<ItemSubCategory> itemSubCategorys;

@OneToOne
private ItemMainCategory itemMainCategory;

 @JsonIgnore
private String summary;



public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<ItemSubCategory> getItemSubCategorys() {
    return itemSubCategorys;
}

public void setItemSubCategorys(List<ItemSubCategory> itemSubCategorys) {
    this.itemSubCategorys = itemSubCategorys;
}

public ItemMainCategory getItemMainCategory() {
    return itemMainCategory;
}

public void setItemMainCategory(ItemMainCategory itemMainCategory) {
    this.itemMainCategory = itemMainCategory;
}

public String getSummary() {
    return summary;
}

public void setSummary(String summary) {
    this.summary = summary;
}

}

获取实体的代码

@Override
public List<ItemParentCategory> getAllItemParentCategoryUnderItemMainCategory(long itemMainCategoryId) {
    //This code works fine
    Query query = sessionFactory.getCurrentSession().getNamedQuery("ItemParentCategory.getAllItemParentCategoryUnderItemMaincategory");
    query.setParameter("itemMainCategoryId", itemMainCategoryId);
    return query.list();

    //This Code return undesired result
    /*Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ItemParentCategory.class);

    ItemParentCategory itemParentCategory  = new ItemParentCategory();

    ItemMainCategory itemMainCategory = new ItemMainCategory();
    itemMainCategory.setId(itemMainCategoryId);

    itemParentCategory.setItemMainCategory(itemMainCategory);

    Example example = Example.create(itemParentCategory);
    criteria.add(example);


    return criteria.list();*/


}

我用的HQL

FROM ItemParentCategory itemParentCategory WHERE itemParentCategory.itemMainCategory.id = :itemMainCategoryId

尝试在您的查询中添加不同的

query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

这里发生的事情是因为您已将 ItemParentCategory 映射到 ItemSubcategory 作为 FetchType.EAGER。

现在,这不会影响您的 HQL 查询,因为 HQL 查询不会遵循 EAGER 映射,并且要急切获取 HQL 中的子类别,您必须在查询中明确定义 FETCH JOIN。因此,在这种情况下一切都很好。

如果您将 HQL 更改为如下所示,您可能会遇到相同的重复问题:

FROM ItemParentCategory ipc JOIN FETCH ipc.itemSubCategorys WHERE ipc.itemMainCategory.id = :itemMainCategoryId

请参阅以下两个常见问题解答:

https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_does_not_return_distinct_results_for_a_query_with_outer_join_fetching_enabled_for_a_collection_even_if_I_use_the_distinct_keyword

https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_ignores_my_outerjointrue_or_fetchjoin_setting_and_fetches_an_association_lazily_using_n1_selects

HQL queries always ignore the setting for outer-join or fetch="join" defined in mapping metadata. This setting applies only to associations fetched using get() or load(), Criteria queries, and graph navigation

示例查询必须以与标准查询类似的方式工作,并且您有 fetch = FetchType.EAGER Hibernate 正在执行显式连接。您应该打开 SQL 日志记录以查看每种情况下实际生成的 SQL。